poj 3648 線段樹成段更新

2022-05-12 22:33:39 字數 1649 閱讀 7908

線段樹成段更新需要用到延遲標記(或者說懶惰標記),簡單來說就是每次更新的時候不要更新到底,用延遲標記使得更新延遲到下次需要更新or詢問到的時候。延遲標記的意思是:這個區間的左右兒子都需要被更新,但是當前區間已經更新了。其主要使用了lazy思想。

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

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

#define _crt_secure_no_deprecate#include

#include

const

int maxn = 100000+10

;typedef

long

long

ll;using

namespace

std;

struct

tnode;

tnode tree[

4*maxn];

intn;

void build(int v, int b, inte)}

void update(int v, int l, int

r, ll value)

tree[v].sum += value*(r - l + 1); //

將增加的值更新進去

int mid = (tree[v].b + tree[v].e) >> 1

;

if (r <=mid)

update(

2 * v + 1

, l, r, value);

else

if (l >mid)

update(

2 * v + 2

, l, r, value);

else

}ll qurrey(

int v, int l, int

r)

int mid = (tree[v].b + tree[v].e) >> 1

;

if (r <=mid)

return qurrey(2 * v + 1

, l, r);

else

if (l >mid)

return qurrey(2 * v + 2

, l, r);

else

return qurrey(2 * v + 1, l, mid) + qurrey(2 * v + 2, mid + 1

, r);

}int

main()

while (q--)

}return0;

}

POJ 3468 線段樹成段更新

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

poj 3467 線段樹成段更新

題意 略 分析 可設一另設兩個域sum 和d分別表示該區間的當前和與該區間的每個元素的增量,之後維護線段樹即可!再次感慨 能力 include using namespace std int64 sum1 int a 100005 struct node tree 1000000 void crea...

POJ 3468 線段樹成段更新

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