線段樹合併

2021-09-24 13:06:13 字數 1279 閱讀 3920

今天寫dsu on tree 的時候發現不會寫線段樹合併,於是滾來寫線段樹合併部落格

對於值域相同的兩個權值線段樹x

xx和y

yy(假設把y

yy合併到x

xx上),每個節點有兩種情況:

其中至少有乙個節點沒有權值(!x

∣∣!y

)(!x||!y)

(!x∣∣!

y)直接x =x

+y

x=x+y

x=x+y(x=

=0?y

:x

)(x==0?y:x)

(x==0?

y:x)

兩個點都有權值

v al

[x]+

=val

[y];

val[x]+=val[y];

val[x]

+=va

l[y]

;統計答案

void merge(int &x,int y)//其中乙個不存在(動態開點)

val[x]+=val[y];

getans(x,y);//統計答案

merge(ls[x],ls[y]);

merge(rs[x],rs[y]);//遞迴

}

luogup3521

樹上逆序對

很裸,每次統計答案

注意卡空間

p.s. cdqz的學長std好像空間是o(n)的,都是什麼神仙啊。。

#include#include#includeusing namespace std;

int read()

int n;

const int n=200010;

long long ans,ans1,ans2,tot;

int ls[n*20],rs[n*20];long long val[n*20];

void modify(int l,int r,int &now,int x)

void merge(int &x,int y)

val[x]+=val[y];

ans1+=val[rs[x]]*val[ls[y]];

ans2+=val[ls[x]]*val[rs[y]];

merge(ls[x],ls[y]);

merge(rs[x],rs[y]);

} void dfs(int &now)else modify(1,n,now,num);

}int main()

線段樹合併

做永無鄉的時候,以為是主席樹合併,後來感覺不對勁,唔。x和y是兩顆樹的根。這個演算法是從歸併演算法那引申的。實際運作的時候,考慮到了線段樹的本質 線段樹有效節點就是葉子節點。好像是句廢話。其實不是,這句話啟發我們並不需要合併一整棵樹,我們只需要處理好葉子節點,考慮把y樹合併到x上,那麼把y樹的葉子節...

線段樹合併

某一天馬學長給我看了乙個lca的題目,然而確實是lca 樹上差分,但是僅僅有lca和樹上差分解決不了,然後我就去面向題解程式設計了。可是這個線段樹合併是個什麼東東。然而今天看書,突然看到了這個線段樹合併。就寫一下了。mmh。p4556 vani有約會 雨天的尾巴 題目背景 深繪里一直很討厭雨天。灼熱...

線段樹合併

線段樹合併雖說是比較基礎的內容,且我一直都知道大概的實現方式,但直到最近我才正式去寫過一次,我真的太弱了啊。下面從暴力合併開始,依次介紹幾種線段樹合併的方式。直接暴力摳出線段樹中的元素,然後暴力合併。總合併時間複雜度應為 o n 2logn 應該算是暴力合併的一種優化。即,每次合併時選取較小的一棵線...