ZKW線段樹區間加區間取最值

2021-10-09 00:04:27 字數 1276 閱讀 8906

本來以為是和zkw單點修改之類的簡單技巧,但是今天卡常的時候學習了一下發現有點離譜。rx

tr_x

trx​

,表示max⁡f

ax

−max⁡x

\max_ - \max_

maxfax

​​−maxx​

,也就是線段樹上乙個節點和他父親區間最大值的差分,我們現在可以知道乙個線段樹上乙個整區間的最大值就是他到根的和。

那麼我們求區間最大值,就是對於乙個區間分成的log⁡n

\log n

logn

個整區間分別求到根的和。

可以通過簡單的技巧在極小常數的o

(log⁡n

)o(\log n)

o(logn

)內完成,具體看**。

區間加x

xx,那麼我們找到區間最左邊的點的葉子和最右邊的點的葉子。

然後一起往上爬,如果左邊的那個點是父親的左兒子,那麼右兒子的trtr

tr需要加上x

xx。(右邊同理)

但是這樣修改之後父親的最大值可能會變化,他的trtr

tr就不對了,那麼我們需要維護父親的trtr

tr,具體看**。

所以這種線段樹式的差分使得我們可以拋棄懶標記,從而使常數和樹狀陣列一樣優秀。

打懶標記的線段樹在比較差的評測機上是一秒跑不過1e6的,這也是寫這篇部落格的目的,大概常數是一般線段樹的3

5\frac 35

53​

c od

e\mathcal code

code

#define lc u<<1

#define rc lc|1

int mx[maxn <<2]

, ans[maxn]

, m;

inline

void

upd(

int u)

void

add(

int l,

int r)

for(

;l !=

1;l >>=1)

upd(l >>1)

;}intqry

(int l,

int r)

int ans =

max(la + mx[l]

, ra + mx[r]);

for(

;l >1;

) ans +

= mx[l >>=1]

;return ans;

}

線段樹 區間加區間乘

給出序列 a1,a2,an 0 ai 109 有關序列的四種操作 1.al,al 1,ar 1 l r n 加上 x 103 x 103 2.al,al 1,ar 1 l r n 乘上 x 103 x 103 3.al,al 1,ar 1 l r n 變成 x al,x al 1 x ar 103 ...

線段樹,區間最值

codeforces 91b queue 線段樹,區間最值 題意是,對於給定區間內的每個元素,要求求出離他最遠的那個元素之間的距離。可以維護乙個線段樹的最小值,每次對於乙個元素,查詢其最右邊的元素的位置。include include include includeusing namespace s...

線段樹動態開點區間加區間求和

陝西師範大學第七屆程式設計競賽網路同步賽 h.萬惡的柯怡 保證葉子節點被完整的覆蓋,需要開節點,就把左右兒子都開出來,其餘和普通線段樹一樣。用結構體內部函式,記憶體不足,第一次遇見本地問題不嚴重 不明嚼慄?include typedef long long ll const int n 400001...