在一些計數問題中,線段樹用於維護值域(一段權值範圍),這樣的線段樹也稱為權值線段樹。為了降低空間複雜度,我們可以不建出整棵線段樹的結構,而是在最初只建立乙個根節點,代表整個區間,當需要訪問線段樹的某棵子樹(某個子區間)時,再建立代表這個子區間的節點。採用這種方法維護的線段樹稱為動態開點的線段樹。動態開點的線段樹拋棄了完全二叉樹父節點的2倍編號規則,改為使用變數記錄左右子節點的編號(相當於指標)。同時,它也不再儲存每個節點代表的區間,而是在每次遞迴訪問的過程中作為引數傳遞。下面是乙個動態開點的線段樹的節點結構。
struct segment_treetree[maxn<<2];int root,tot;
inline int build()
int main()
下面的**對線段樹單點修改的過程稍加變動,實現了在動態開點的線段樹中把val位置上的值加delta,同時維護區間最大值的操作
inline void update(int p,int l,int r,int val,int delta)int mid = (l+r)>>1; //代表的區間[l,r] 作為遞迴引數傳遞
if(val <= mid)
else
tree[p].dat = max(tree[tree[p].lc].dat,tree[tree[p].rc].dat);
}
線段樹動態開點
為了降低權值線段樹的空間複雜度,可以不直接建出整棵線段樹的結構,而是在最初只建立乙個根節點,當需要訪問某棵為建立的子樹的時候,再建立代表這個子樹的節點。動態開點的線段樹用變數記錄左右節點的編號。值域為1 n的動態開點線段樹在m次單點修改後,節點規模為o mlogn 例題 p1908 逆序對 這題n最...
動態開點線段樹
前置芝士 眾所周知,普通線段樹空間複雜度是 o n 4 所以當n很大的時候,如果正常的去建一顆線段樹,開4倍n空間顯然會炸記憶體 怎麼辦呢?這個時候,動態開點線段樹出現了。概念 動態開點線段樹是一類特殊的線段樹,與普通的線段樹不同的是,每乙個節點的左右兒子不是該點編號的兩倍和兩倍加一,而是現加出來的...
權值線段樹 動態開點
普通平衡樹 題目給的資料是1e 7到1e7,直接寫線段樹記憶體肯定是比較吃力,而且題目還要維護rank和第k大,這時候就用到動態開點了,因為運算元一共就1e5,所以最多也只需要開 log 2 2e7 大小的陣列。修改函式void add int rt,int l,int r,int x,int v ...