線段樹模板

2021-07-23 19:04:54 字數 2016 閱讀 1664

處理區間問題的利器——線段樹,每個節點表示一段區間的一些資訊,因為查詢和更新都是從樹頂往下推的所以沒有必要把所管理的區間左右端點顯示的儲存在節點中,使用的時候用乙個陣列表示,是一棵完全二叉樹所以

lc

=o<<

1 rc

=o<<1|

1

用位運算加快速度。

給定乙個數列a1

,...

,ai,

...,

an有兩個操作query ql,qr,求出這個區間的最大值,或者最小值,

update x v將a[x] 修改為v;

點更新

void update(int o,int l,int r,int p,int v)//p為修改點

}

區間查詢

int query(int o,int l,int r,int ql,int qr)

}

建樹

採用遞迴建樹o(

nlgn

) ,其他操作的建樹操作也是一樣的

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

else

}

給定乙個數列a1

,...

,ai,

...,

an有兩個操作query ql,qr,求出這個區間的最大值,或者最小值,還有和, ad

dl,r

x 對區間al

,al+

1,..

.,ar

都加上乙個值 x

這個不同於點更新了,我們在其中使用了乙個技巧,即只更新為一些不相交的區間的節點進行相加,這樣一次更新可以保證在o(

lgn)

的時間內解決這個問題

void update(int o,int l,int r,int y1,int y2,int v)

maintain(o,l,r);

}

maintain

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

seg[o].min += seg[o].addv;seg[o].max+=seg[o].addv;

seg[o].sum+=seg[o].addv*(r-l+1);

}

區間查詢

int _sum,_min,_max;

//查詢再統計累加值

void query(int o,int l,int r,int ql,int r,int addv)

else

}

l,

r,這之間的元素全部設定為v

下推與上推

void push_up(int o)

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

}

區間更新

void update(int o,int l,int r,int y1,int y2,int v)

else

}

查詢

int _sum;

void query(int o,int l,int r,int ql,int qr)

else

if(ql<=l && qr>=r)

else

}

建樹

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

else

}

線段樹模板(模板)

參考部落格 持續更新。外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳 img xhrgdjcd 1613976863463 區間儲存在陣列中的下標對應為 12 3 4 5 6 7 8 9 10 11 12 13 14 15 四部分單點更新 根據題目的要求編寫自己的pushup,query...

線段樹模板

include include include using namespace std const int size 10010 struct node the node of line tree class linetree void updatem void updateline public ...

線段樹模板

單點更新,區間求最值 include include include include include define n 222222 using namespace std int num n struct tree tree n 4 void push up int root void build...