單調佇列與線段樹與樹狀陣列

2021-10-19 07:41:37 字數 1391 閱讀 4381

更新中……

線段樹給定乙個陣列,依次求所有長度為 m

mm 的區間的元素最大值與最小值。

構建乙個空佇列。

以求最小值為例,從左往右掃瞄一遍陣列。 如果隊首元素所在位置超過了區間範圍,則將其彈出。每當掃瞄到乙個元素時,將佇列末尾大於其的一部分捨棄,並將其放置在佇列尾。

由此得到的佇列是單調遞增的,並且隊首元素是當前區間的最小值。

洛谷:p1886 滑動視窗 /【模板】單調佇列

**:

#include

#include

#include

#include

#include

#include

#include

#define con(_c,_t,_f) ((_c)?(_t):(_f))

#define ll long long int

#define max 9000000

using

namespace std;

ll q[max*3]

;int head=

0, tail=0;

// [head,tail)

bool

empty()

ll front()

ll back()

void

push

(ll x)

ll a[max]

;int n,k;

intmain()

printf

("\n");

head=tail;

for(

int i=

0;i)}

乙個陣列,每次操作是一次維護或一次詢問:

當陣列很大時,這樣的操作時間複雜度最壞可以達到 o(q

⋅n

)o(q\cdot n)

o(q⋅n)

,其中 q

qq 是操作次數, n

nn 是陣列長度。

線段樹可以將操作的時間複雜度降低至 o(q

⋅log

n)

o(q\cdot logn)

o(q⋅lo

gn)。

線段樹思想**於二分,將整個線段二分,二分成的子線段繼續二分,如此往復,直到單位線段。

查詢乙個單元時,它必定僅屬於兩條子線段之一,遞迴訪問即可查詢,修改乙個單元同理。

問題是查詢和修改乙個區間。其實也不難,只需要在每個節點處新增乙個標記,每次向下訪問時傳遞這個標記。如果某一次需要的操作恰好是對這個完整區間進行操作,則可以在此處新增乙個該操作標記,不必再向下訪問,直接折返向上維護至根節點即可。

洛谷:p3372 【模板】線段樹 1

洛谷:p3373 【模板】線段樹 2

洛谷:p4588 [tjoi2018] 數學計算

樹狀陣列與線段樹

推一下關於樹狀陣列的講解部落格 和線段樹的講解 package test2 public class 線段樹 int len a.length segtree t buildtree 0,len 1,a int sum0 2 query t,0,2 int sum1 3 query t,1,3 查詢...

樹狀陣列與線段樹(三)

找規律題 1.螺旋折線 如下圖所示的螺旋折線經過平面上所有整點恰好一次。對於整點 x,y 我們定義它到原點的距離 dis x,y 是從原點到 x,y 的螺旋折線段的長度。例如 dis 0,1 3,dis 2,1 9 給出整點座標 x,y 你能計算出 dis x,y 嗎?輸入格式 包含兩個整數 x,y...

樹狀陣列與線段樹(二)

樹狀陣列 1.小朋友排隊 n n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。每個小朋友都有乙個不高興的程度。開始的時候,所有小朋友的不高興程度都是 0 0 如果某個小朋友第一次被要求交換,則他的不高興程度增加 1 1 如果第二次要求他交換,則他的不...