日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

长链剖分(知识点整理+板子总结)

發(fā)布時(shí)間:2023/12/20 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 长链剖分(知识点整理+板子总结) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

思路來(lái)源

https://blog.nowcoder.net/n/5eaebd22f5f846838c637bc337cc1ee9

https://blog.csdn.net/litble/article/details/87965999

知識(shí)點(diǎn)整理

長(zhǎng)鏈剖分,用于維護(hù)子樹(shù)中只與深度有關(guān)的信息,多用于靜態(tài)

從任何一個(gè)點(diǎn)往上跳到根,最多經(jīng)過(guò)條不同的長(zhǎng)鏈。

?

長(zhǎng)鏈剖分,顧名思義,每個(gè)點(diǎn)維護(hù)子樹(shù)中最長(zhǎng)的那一條鏈,

[l[x],l[x]+len[x]-1]是其長(zhǎng)鏈區(qū)間,到l[x]的偏移量也確定了它的深度

和dsu on tree類似,但若干條鏈分別占用不同位置的數(shù)組空間,只有相同鏈的內(nèi)存共用,

所以不用像dsu on tree那樣清空內(nèi)存,所以預(yù)處理長(zhǎng)鏈長(zhǎng)度之后,只需要三步

?

①搜長(zhǎng)兒子,繼承長(zhǎng)兒子的答案

②把短兒子往長(zhǎng)兒子上掛,計(jì)算短兒子的答案

③把自己這個(gè)節(jié)點(diǎn)掛上去

?

由于若干條長(zhǎng)鏈不交,每個(gè)點(diǎn)在向上合并的時(shí)候,只會(huì)作為短鏈出現(xiàn)在一條鏈里,所以是O(n)的

似乎還是指針版的略快一點(diǎn),然而習(xí)慣用數(shù)組下標(biāo)寫……

題目

n(n<=1e6)個(gè)點(diǎn)的樹(shù),

對(duì)于每個(gè)點(diǎn),求其子樹(shù)中出現(xiàn)節(jié)點(diǎn)最多的深度d,

如果存在多個(gè)深度,它們的節(jié)點(diǎn)個(gè)數(shù)相同,則返回最小的哪個(gè)

題解

搞個(gè)裸題,長(zhǎng)鏈剖分合并,

首先繼承長(zhǎng)鏈答案,然后短鏈合并的時(shí)候,如果可更新則更新

最后check一下這棵子樹(shù)的根的深度,判斷其是否能更新答案

代碼

#include<bits/stdc++.h> using namespace std; #define pb push_back const int N=1e6+10; int son[N],len[N];//長(zhǎng)兒子 int n,u,v; int l[N],r[N],dfn;//長(zhǎng)鏈的dfs序區(qū)間段 int sum[N],ans[N]; vector<int>e[N]; void dfs1(int u,int fa){for(int v:e[u]){if(v==fa)continue;dfs1(v,u);if(!son[u] || len[son[u]]<len[v]){son[u]=v;}}len[u]=len[son[u]]+1; } void dfs2(int u,int fa){l[u]=++dfn;r[u]=l[u]+len[u]-1;if(son[u]){dfs2(son[u],u);ans[u]=ans[son[u]]+1;//答案來(lái)自長(zhǎng)兒子 }for(int v:e[u]){if(v==fa || v==son[u])continue;dfs2(v,u);//答案來(lái)自短兒子 for(int j=l[v],k=1;j<=r[v];++j,++k){sum[l[u]+k]+=sum[j];if((k>ans[u] && sum[l[u]+k]>sum[l[u]+ans[u]]) || (k<ans[u] && sum[l[u]+k]>=sum[l[u]+ans[u]])){ans[u]=k;}}}sum[l[u]]++;if(sum[l[u]]>=sum[l[u]+ans[u]]){ans[u]=0;} } int main(){scanf("%d",&n);for(int i=2;i<=n;++i){scanf("%d%d",&u,&v);e[u].pb(v);e[v].pb(u);}dfs1(1,0);dfs2(1,0);for(int i=1;i<=n;++i){printf("%d\n",ans[i]);}return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的长链剖分(知识点整理+板子总结)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。