可持久化線段樹學習筆記

2022-02-04 15:56:01 字數 1221 閱讀 6671

模板

#includeusing namespace std;

const int n=2e5+10;

int cnt,rt[n];

int n,a[n],t[n],t;

int ls[n*20],rs[n*20],dat[n*20];

void copy(int x,int y)

int build(int l,int r)

int insert(int pre,int l,int r,int x)

int query(int p,int q,int l,int r,int k)

int main()

sort(t+1,t+n+1);

int m=unique(t+1,t+n+1)-(t+1);

rt[0]=build(1,m);

for(int i=1;i<=n;i++)

while(t--)

return 0;

}

可持久化線段樹

共用節點的\(n\)棵線段樹。

可持久化權值線段樹也稱主席樹

例題樹上第\(k\)大。

注意的兩個點:

結點\(u\)應該在\(fa_u\)的基礎上建樹。

\(lca\)求距離時是這樣的:\(dis_u+dis_v\)

\(-\)

\(2\times dis_}\),這個題應該是\(dis_u+dis_v\)

\(-\)

\(dis_}\)

\(-\)

\(dis_}}\)。

不錯的題目,不是建權值線段樹了,middle題解

先求字首和。

因為子段長度有\(l\)和\(r\)的限制,如果固定左端點\(l\),右端點\(r\)就在一段固定的區間裡選擇。

要使\(sum_r-sum_l\)最大,那麼\(sum_r\)就應該盡量大。

有個很常見的二叉堆貪心技巧,就是下面的做法:

建立乙個大根堆,以\(val\)為指標,每個元素是乙個三元組\((l,c,val)\)表示以\(l\)為左端點選到了第\(c\)大的右端點,子段值為\(val\)。

先插入每個\((i,1,val)\)。

每次取出堆頂,加上它的\(val\),然後通過\(l\)查詢選定區間第\(k+1\)大的\(val'\),然後插入\((l,c+1,val')\),很顯然可以主席樹。

執行第\(3\)個步驟\(k\)次。輸出結果。

學習筆記 可持久化線段樹

例題 luogu 3919 特點 在普通線段樹支援查詢當前狀態基礎上,支援查詢過去的所有版本 一 text 暴力儲存過去版本,每一次修改都會造成 nlogn 的時空複雜度,總複雜度 o mnlogn 直接上天 注意到每一次單點修改只會導致對應的葉子節點以及它的所有祖先儲存的值改變,我們可以考慮只儲存...

可持久化線段樹學習筆記

可持久化,即對資料修改後仍可查詢到其歷史版本。以模板題為例 p3919 模板 可持久化線段樹 1 可持久化陣列 單點修改 查詢的可持久化。暴力時空複雜度 o nm 版本複製 m 修改查詢 可持久化線段樹 時空複雜度只為 o m log n n 題解口胡 建乙個陣列hed存各版本的對應的線段樹根 對於...

可持久化線段樹學習筆記

可持久化是真的毒瘤,在網上找了很多資料才搞懂 不過我覺得應該是我太蒻了 首先以洛谷上的兩個板子題為例吧 對於第一題,要求詢問區間第k大 第k大指的是從小到大排序的第k個 直接掃是肯定不行的,因此我們需要可持久化線段樹 感覺跳的好快,但是我也不清楚要怎麼表達,就這樣吧,反正知道是要用這個就行了 首先既...