18.12.30 【sssx】線段樹
阿新 • • 發佈:2018-12-30
size 指針 結點 越界 表示 font 復雜 否則 color
每個非葉結點所表示的結點$[a,b]$,左兒子表示區間$[a,\frac{a+b}{2}]$,右兒子表示的區間為$[\frac{a+b}{2}+1,b]$
葉子結點表示區間長度為1
數據結構
struct CNode { int L,R; //區間起點和終點 XXXX ; //與區間[L,R]相關的數據 CNode * pLeft, * pRight; //左右孩子指針(可用idx替代) };
用一維數組存放線段樹(idx)時,數組開到4n大可以確保不越界。
操作
區間分解
- 從根節點開始遞歸進行區間分解
- 走到結點$[L,R]$時,如果該結點就是要找的區間,則找到終止結點,
如果不是,則:取$mid=\frac{L+R}{2}$
看要分解的區間與$[L,mid]$或$[mid+1,R]$哪個有交集,就進入哪個區間進行進一步分解,有可能兩個區間都進入。
- 復雜度$O(log(n))$
構建
- 遞歸建樹,對根節點v建樹,v為$[L,R]$
- 對每個結點,如果L!=R,建立左孩子$[L,\frac{L+R}{2}]$,右孩子$[\frac{L+R}{2}+1,R]$
- 復雜度:$O(n)$,n為根節點對應的區間長度
解題技巧
- 讀時更新(參見POJ 3468
- 更新時,加的區間正好覆蓋一個結點,增加其節點的inc值,不再往下走,否則更新sum, 繼續往下。
- 查詢時,待查區間不是正好覆蓋一個結點就將結點的inc往下帶到下一層(累加),並且每次將結點更新到真正的sum,再往下查詢
- 更新時,加的區間正好覆蓋一個結點,增加其節點的inc值,不再往下走,否則更新sum, 繼續往下。
- 離散化
18.12.30 【sssx】線段樹