poj3468 線段樹成段更新模板題

2021-06-22 21:15:40 字數 1805 閱讀 4412

題意:包括兩個操作:1、將[a.b]上的數字加上v;2、查詢區間[a,b]上的和

下面的介紹是下解題思路:

首先介紹  lazy-tag思想:用乙個變數記錄每乙個線段樹節點的變化值,當這部分線段的一致性被破壞我們就將這個變化值傳遞給子區間,大大增加了線段樹的效率。

比如現在需要對[a,b]區間值進行加c操作,那麼就從根節點[1,n]開始呼叫update函式進行操作,如果剛好執行到乙個子節點,它的節點標記為o,這時tree[o].l == a && tree[o].r == b 這時我們可以一步更新此時o節點的sum[o]的值,sumo] += c * (tree[o].r - tree[o].l + 1),注意關鍵的時刻來了,如果此時按照常規的線段樹的update操作,這時候還應該更新o子節點的sum值,而lazy思想恰恰是暫時不更新o子節點的sum值,到此就return,直到下次需要用到o子節點的值的時候才去更新,這樣避免許多可能無用的操作,從而節省時間 。

**如下:

#include#include#include#include#include#include#include#include#include#include#include#include#define ll __int64

#define n 100005

#define inf 0x7ffffff

#define eps 1e-9

#define pi acos(-1.0)

#define p system("pause")

using namespace std;

struct node

tree[n<<2];

ll a[n];

void pushup(int o)//用於更新根節點

void build(int o,int l,int r)

int m = (l+r)/2;

build(2*o,l,m);

build(2*o+1,m+1,r);

pushup(o);

}void pushdown(int o)//用於更新子節點

}void update(int o,int x,int y,int v)

if(tree[o].l == tree[o].r) return;

pushdown(o);

int m = (tree[o].r+tree[o].l)/2;

if(y <= m)

update(2*o,x,y,v);

else if(x > m)

update(2*o+1,x,y,v);

else

pushup(o);

}ll query(int o,int x,int y)

return res;

}int main()

if(str[0] == 'q')}}

return 0;

}

最後還有幾點補充,

在update函式中,if(tree[o].l == x && y == tree[o].r) 這裡就是用到lazy思想的關鍵時刻 正如上面說提到的,這裡首先更新該節點的sum[o]值,然後更新該節點具體每個數值應該加多少即add[o]的值,注意此時整個函式就執行完了,直接return,而不是還繼續向子節點繼續更新,這裡就是lazy思想,暫時不更新子節點的值。那麼什麼時候需要更新子節點的值呢?答案是在某部分update操作的時候需要用到那部分沒有更新的節點的值的時候,這時就掉用pushdown()函式更新子節點的數值。

對於pushdown()函式,就是從當前根節點rt向下更新每個子節點的值,這段**讀者可以自己好好理解,這也是lazy的關鍵。

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...