題面傳送門
線段樹每個根節點管理下面的兩個葉子節點,線段樹的每乙個節點都分管區間,其中若根節點分管區間是\(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,右節點編號為...