闊力梯的樹 樹上啟發式合併 set

2021-10-13 15:27:18 字數 3075 閱讀 8495

傳送門

人都傻了

d su

dsuds

u倒是模板,被set

setse

t的操作搞暈了…

s .l

ower

_bou

nd(i

nt

)s.lower\_bound(int)

s.lowe

r_bo

und(

int)

返回乙個大於等於查詢元素的指標

s .e

nd()

s.end()

s.end(

)是se

tset

set的末尾位置,但是最後乙個元素在末尾位置的前面!!!

!!!!!

! 當l ow

er_b

ound

lower\_bound

lower_

boun

d返回s.e

nd()

s.end()

s.end(

)說明沒找到這個元素

至於這裡用set

setse

t也是有原因的,因為編號不重複,否則需要使用mul

tise

tmultiset

multis

et回到這道題,維護每個點的結實度

顯然想知道乙個點的結實度必須要把所有子節點的編號排成乙個序列計算

但是直接計算是o(n

2)

o(n^2)

o(n2)的

考慮到這個序列是可以合併的,答案也是小幅度修改,可以使用dsu

dsuds

u 使用s et

setse

t來儲存當前子樹內的編號序列

加入乙個編號時,直接low

er_b

ound

lower\_bound

lower_

boun

d找到插入的前驅後繼,累加權值

刪除時同理

這樣就變成模板了

插入時分四種情況來寫set

setse

t內元素個數只有111個

無前驅無後繼

有前驅和後繼

刪除同理

然後就直接套用dsu

_on_

tree

dsu\_on\_tree

dsu_on

_tre

e的模板

#include

using

namespace std;

#define int long long

const

int maxn =

2e5+10;

struct edged[maxn]

;int head[maxn]

,cnt=1;

void

add(

int u,

int v)

,head[u]

= cnt;

}int n,m,son[maxn]

,siz[maxn]

,sum,son,ans[maxn]

;void

dfs(

int u)

}set<

int>s;

set<

int>

::iterator it;

intpre

(set<

int>

::iterator it)

intnxt

(set<

int>

::iterator it)

void

add(

int u)

it = s.

lower_bound

(u);

//找到第乙個大於等於的

int pr =

pre(it)

, nx =

*it;

if( it==s.

begin()

) sum +

=(nx-u)

*(nx-u)

;else

if( it==s.

end(

)) sum +

=(u-pr)

*(u-pr)

;else

s.insert

(u);

}void

del(

int u)

it = s.

lower_bound

(u);

int pr =

pre(it)

,nx =

nxt(it);if

( it==s.

begin()

) sum -

=(nx-

*it)

*(nx-

*it)

;elseif(

*it==

pre(s.

end())

) sum -

=(pr-

*it)

*(pr-

*it)

;else

s.erase

(u);

}void

cal(

int u,

int type)

}void

dsu(

int u,

int type)

if( son[u]

)dsu

( son[u],1

),son = son[u]

;cal

(u,1

); ans[u]

= sum; son=0;

if(!type )

cal(u,0)

;}signed

main()

dfs(1)

;dsu(1

,1);

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,ans[i]);

}

樹上啟發式合併

解決樹上統計問題,o n log n o n log n o n lo g n 可以結合線段樹等資料結構維護深度上的資訊 部落格 入門題 const int maxn 1e5 7 const int mod 1e9 7 ll n,m,u,v,mx,sum vector int mp maxn int...

樹上啟發式合併

樹上啟發式合併,一種美妙的黑科技,可以用普通的優化讓你 n 2 變成嚴格 n log 解決一些類似 樹上數顏色,樹上查眾數 這樣的問題 首先你要知道暴力為什麼是 n 2 的 以這個圖為例 每次你從乙個節點開始向下搜,你從1節點搜到3,搜完這個子樹然後你需要把3存的col等資訊刪去再遍歷另乙個子樹才是...

樹上啟發式合併總結

某一天發現一道樹上啟發式合併裸題,但我不會寫 學習並刷了兩天的題,是時候來寫個總結了 樹上啟發式合併 dsu on tree 是乙個在o n logn o nlogn o nlog n 時間內解決許多樹上問題的有力演算法。但它的中心其實是 暴力!沒錯,它正是由暴力優化而來。我們先看一道例題 cf60...