POJ 3468 線段樹(成段更新,區間求和)

2022-07-17 05:27:07 字數 1495 閱讀 2016

這個線段樹運用了應用了add域優化,每個節點除了用value記錄當前節點對應區間元素的和之外,還要用add域記錄當前節點對應區間每個元素的增量。這樣,沒必要每次更新都要更新value更新到最底層每乙個點,只需要將增量記錄在某父節點的add域中即可,如果下次查詢或者更新操作的是該父節點對應區間的子區間,那麼就將add域更新下去,更新子節點的value值,完成更新或查詢。add域優化可以減少時間複雜度。

還有就是要注意查詢或者更新的區間遊客能橫跨左子樹和右子樹,在判斷的時候應該做處理。

#include #include 

#include

using

namespace

std;

#define maxn 4000000

struct

node

tree[maxn];

__int64 a[maxn],n;

void build( __int64 v, __int64 l,__int64 r ) //

對節點v進行建立,區間為l到r

__int64 mid=( l+r )/2

; build( v*2,l,mid ); //

左兒子 build( v*2+1,mid+1,r ); //

右兒子 tree[v].value=tree[v*2].value+tree[v*2+1].value; //

根據左右兒子更新當前節點

}void update(__int64 v,__int64 l,__int64 r,__int64 m) //

更新區間l-r加上m

if (tree[v].l==tree[v].r) return

;

__int64 mid=(tree[v].l+tree[v].r)/2

;

if (tree[v].add) //

下邊沒更新,傳遞增量

if (r<=mid)

if (l>mid)

update(v*2,l,mid,m); //

左右兒子都更新

update(v*2+1,mid+1

,r,m);

}__int64 query( __int64 v,__int64 l,__int64 r)

//查詢l-r上的v值

if (r<=mid)

return query(v*2,l,r); //

要查詢的區間全在左兒子

if (l>mid)

return query(v*2+1,l,r); //

全在右邊

return query(v*2,l,mid)+query(v*2+1,mid+1,r); //

橫跨左右邊

}int

main()

else

}return0;

}

暑假做的,又熟悉了一遍。。

POJ 3468 線段樹成段更新

題意就是給了一串行的數.然後不斷的問一段的值或者在一段上每個數加乙個數.輸出每次詢問的值.初看這題感覺就是最一般的線段樹成段更新的應用.但下手後發現很多細節.對於一向很粗心的我調了很久才給調出來.成段更新前一文已經提到過.這裡再通過這一題補充一些很值得注意的地方 1 前乙個題因為只有最後才要輸出一段...

POJ 3468 線段樹成段更新

很久以前的題目再做一遍複習一下。要點 1 約定在任何時候 add num 到達節點的時候就立即更新節點的 sum 值。2 每次更新節點回溯的時候記得維護節點的 sum 值。3 執行詢問操作的時候,遇到 lazy 標記為1 的時候往下 push down,同時記得第一點 4 遇到符合要求的詢問區間時,...

poj 3468線段樹 成段更新

題意和題目都很簡單,就是線段樹的成段更新,只要做一下延遲標記就好了。題意 查詢一段數的和,和更新一段數的值。一開始出了點錯誤,忘在更新時做延遲標記了。includelong long sum 100010 2 long long add 100010 2 void push up int rt vo...