線段樹與延遲標記

2022-09-07 20:48:21 字數 2167 閱讀 2962

線段樹(segmenttree)是一種基於分治思想的二叉樹結構,用於區間上進行資訊統計。與按照二進位制位進行劃分的樹狀陣列相比,線段樹是一種更加通用的結構。

性質

線段樹每個節點都代表乙個區間。

線段樹具有唯一的根節點,代表的區間是整個統計範圍。

線段樹的每個葉節點都代表乙個長度為1的元區間.

對於每個內部節點[l, r],它的左子節點是[l, mid],右子節點是[mid+1, r],其中mid = (l + r) >> 1。

建樹

每個葉節點t[i, i]維護a[i]的值,從而使資訊從下向上傳遞資訊。

單點更改

從根節點出發,找到區間[x, x]的葉節點,然後從下向上更新。

區間查詢

找到完全覆蓋當前節點的區間,立即回溯。

若左子節點有重合的部分,則訪問左子節點。

若右子節點有重合的部分,則訪問右子節點。

延遲標記

區間修改的指令中,某個區間的結點改變,整棵子樹中的所有節點儲存的資訊都會發生變化,修改的時間複雜度將會增加到o(n)。

我們發現,若我們將區間的整棵子樹進行更新,卻始終沒有進行查詢,那麼整棵子樹的更新都是徒勞的。所以,我們可以在修改指令時找到完全覆蓋的區間後立即返回,只是在其中增加乙個標記,表示此節點已經更改,但子樹都未更新。

此後的更改和查詢命令中,在向下訪問之前,我們先將未更新的結點向下傳遞,然後清除當前結點的標記。這樣一來,時間複雜度仍可維持在o(logn)。

模板:

如題,已知乙個數列,你需要進行下面兩種操作:

1.將某區間每乙個數加上x

2.求出某區間每乙個數的和

輸入格式:

第一行包含兩個整數n、m,分別表示該數列數字的個數和操作的總個數。

第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。

接下來m行每行包含3或4個整數,表示乙個操作,具體如下:

操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k

操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和

輸出格式:

輸出包含若干行整數,即為所有操作2的結果。

1 #include2

using

namespace

std;

3const

int size = 100005;4

struct

segmenttreet[size*4];8

inta[size], n, m;910

void build(int p, int l, int

r)16

int mid = (l + r) >> 1

;17 build(p*2

, l, mid);

18 build(p*2+1, mid+1

, r);

19 t[p].sum = t[p*2].sum + t[p*2+1

].sum;20}

2122

void spread(int

p)30}31

32void change(int p, int l, int r, int

d)38

spread(p);

3940

int mid = (t[p].l + t[p].r) >> 1;41

if(l <= mid) change(p*2

, l, r, d);

42if(r > mid) change(p*2+1

, l, r, d);

43 t[p].sum = t[p*2].sum + t[p*2+1

].sum;

44}

4546

long

long ask(int p, int l, int

r)55

56int

main() 72}

73return0;

74 }

延遲標記 線段樹

延遲標記 例題以poj3468為例,我們使用線段樹 延遲標記技巧 來實現快速區間修改與區間查詢。具體做法是,我們為每個節點增加乙個延遲標記add,如果add為0,則說明該點的所有子區間都已更新完成,否則說明其子區間仍需要 add。請注意,如果乙個節點被打上 延遲標記 說明該節點曾經被修改過,但其子節...

延遲標記 線段樹

以poj3468為例,我們使用線段樹 延遲標記技巧 來實現快速區間修改與區間查詢。具體做法是,我們為每個節點增加乙個延遲標記add,如果add為0,則說明該點的所有子區間都已更新完成,否則說明其子區間仍需要 add。請注意,如果乙個節點被打上 延遲標記 說明該節點曾經被修改過,但其子節點尚未被更新,...

線段樹模板 (poj 3468)延遲標記

參考了胡浩大牛的 風格。include define lson l,m,rt 1 define rson m 1,r,rt 1 1 const int maxn 100010 long long add maxn 4 1 long long sum maxn 4 1 void pushup int ...