線段樹學習筆記

2022-05-11 13:55:19 字數 2155 閱讀 4835

題面傳送門

線段樹每個根節點管理下面的兩個葉子節點,線段樹的每乙個節點都分管區間,其中若根節點分管區間是\(x\),\(y\),那麼左兒子區間為\(x\),\((x+y)>>1\),右兒子分管區間是\(((x+y)>>1)+1\),\(y\).

我們定義\(f\)陣列,以\(f_x\)表示\(x\)這個節點所管理的區間統一加了多少,定義\(sum_x\)表示\(x\)這個節點所管理的區間的和為多少。

線段樹主要有三個環節:建樹,修改,查詢

建樹:這很好建,乙個遞迴,每一層的值為返回的兩個兒子的值的和,葉子結點返回本來的單個單元的值,複雜度\(o(nlog^2n)\)。不要被這麼高的複雜度嚇到,畢竟總共就建一次樹。

查詢:線段樹把乙個區間分成好幾個長度為二進位制的區間之和,而二進位制查詢需要乙個遞迴。

對於我們要把\(x\)到\(y\)的區間加上\(z\),在進行到乙個節點時,進行三種判斷:若是查詢區間包含這個節點所管理的區間,那麼\(f_\)加上\(z\),\(return\)。若是\(x\)落在左兒子內,遞迴下去。若是\(y\)落在右兒子內,也遞迴下去。同時為了好理解,我們做乙個下推動作,把\(f_x\)推到兩個兒子的\(f\)陣列中,把兩個兒子的\(sum\)加上推下來的值。並把\(f_x=0\).這樣已經做過的\(sum\)的值就表示這個節點所管轄的區間的和值。

查詢:在查詢\(x\)到\(y\)時我們也和修改一樣。進行三種判斷:若是查詢區間包含這個節點所管理的區間,返回乙個\(sum\),\(return\)。若是\(x\)落在左兒子內,遞迴下去。若是\(y\)落在右兒子內,也遞迴下去。也同時下推,這樣能保證值一定是正確的。

個人理解:其實線段樹的優點就在於是拆解而不是像樹狀陣列一樣作差。不過缺點就是常數太大。但有\(zkw\)非遞迴式線段樹常數較小。線段樹當優化後可以是一種很好的資料結構,他的適用範圍很廣。

**實現:

#include#define re register

long long n,m,a[200039],x,y,z,f[800039];

long long s[800039];

inline void read(long long &x)

while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+(s^48),s=getchar();

x*=fs;

}inline void print(re long long x)

if(x>9)print(x/10);

putchar(x%10+'0');

}inline long long jianshu(re int now,re int l,re int r)

inline void push(re int l,re int r,re int now)

inline void get(int l, int r,int now)

register int m=(l+r)>>1;

push(l,r,now);

if(x<=m) get(l,m,now<<1);

if(y>m) get(m+1,r,now<<1|1);

s[now]=s[now<<1]+s[now<<1|1];

return;

}inline long long find(int l,int r,int now)

int main()

else

} return 0;

}

同時我們也可以看看乙個應用

題面傳送門

這道題是貪心和線段樹的結合,貪心思想有點像凌亂的yyy/線段覆蓋。把奶牛們按右端點排序,並用遍歷所有地點可上車的奶牛,若可上車挑選下車最晚的位置上車,這樣能做到最優,並記錄總牛數。而挑選下車最晚的位置上車可以用線段樹維護。

**實現:

#include#includeusing namespace std;

int n,m,k,sum[1039],ans,tot,f[1039],x,y,fs[1039];

struct yyya[50039];

char s;

inline void read(int &x)

inline bool cmp(yyy a,yyy b)

int main()

} printf("%d",ans);

return 0;

}

線段樹學習筆記

線段樹是一種 二叉搜尋樹 與區間樹 相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。使用線段樹可以快速的查詢某乙個節點在若干條線段中出現的次數,時間複雜度為o logn 而未優化的 空間複雜度 為2n,因此有時需要離散化讓空間壓縮。以下筆記摘自lcomyn神犇部落格 1....

線段樹學習筆記

本文筆記在參考一步一步理解線段樹 tenos的基礎上形成 線段樹,也是二叉搜尋樹的一種,是基於陣列,但是優於陣列的一種資料結構。同時結合預處理 時間複雜度一般在o n 使得從原來陣列的o n 的查詢和更新複雜度降到了o logn 在處理很大資料量的資料更新和查詢最值方面變得簡單,值得一提的是,它的構...

線段樹學習筆記

線段樹是一種維護區間的資料結構,且滿足二叉樹的全部性質 下圖是一棵維護區間 1 6 1,6 的線段樹 格式 idl ri dl r我們可以發現,對於每個節點 k k 來說,其左節點編號為2k role presentation style position relative 2k2 k,右節點編號為...