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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ4855 : [Jsoi2016]轻重路径

發(fā)布時間:2025/3/18 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ4855 : [Jsoi2016]轻重路径 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先用樹狀數(shù)組維護dfs序來快速支持一個點子樹大小的詢問。

每次刪掉一個葉子時,從根開始往葉子走,顯然只有$2size[x]\leq size[father]$的點的父親才有可能換重兒子。

從根開始往下,找到最高的滿足條件的點,從那個點開始繼續(xù)迭代,每次點數(shù)至少減小一半,所以迭代只有$O(\log n)$次。

時間復雜度$O(n\log^2n)$。

?

#include<cstdio> const int N=200010; int n,m,x,i,ch[N][2],size[N],f[N],d[N],son[N],top[N],st[N],en[N],q[N],dfn,bit[N];long long ans; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} inline void add(int x,int p){for(;x<=n;x+=x&-x)bit[x]+=p;} inline int ask(int x){int t=0;for(;x;x-=x&-x)t+=bit[x];return t;} inline int getsize(int x){if(!x)return 0;return ask(en[x])-ask(st[x]-1); } void dfs(int x){size[x]=1;for(int i=0;i<2;i++){int y=ch[x][i];if(!y)continue;f[y]=x;d[y]=d[x]+1;dfs(y),size[x]+=size[y];if(size[y]>size[son[x]])son[x]=y;}ans+=son[x]; } void dfs2(int x,int y){q[st[x]=++dfn]=x;top[x]=y;if(son[x])dfs2(son[x],y);for(int i=0;i<2;i++){int o=ch[x][i];if(!o||o==son[x])continue;dfs2(o,o);}en[x]=dfn; } inline int up(int x,int k){while(1){if(st[x]-st[top[x]]>=k)return q[st[x]-k];k-=st[x]-st[top[x]]+1;x=f[top[x]];} } inline void recal(int x){if(!x)return;ans-=son[x];int t=0;for(int i=0;i<2;i++){int y=ch[x][i],w=getsize(y);if(w>t)t=w;}if(!t)son[x]=0;else if(getsize(son[x])!=t){if(getsize(ch[x][0])==t)son[x]=ch[x][0];else son[x]=ch[x][1];}ans+=son[x]; } inline void remove(int x){add(st[x],-1);int lim=d[x],o=lim;while(1){int l=1,r=o,mid,t=0,s=getsize(up(x,o));while(l<=r)if(getsize(up(x,mid=(l+r)>>1))*2<=s)l=(t=mid)+1;else r=mid-1;recal(f[up(x,t)]);if(!o)return;o=t;} } int main(){while(~scanf("%d",&n)){if(!n)return 0;for(dfn=ans=0,i=1;i<=n;i++)size[i]=son[i]=bit[i]=0;for(i=1;i<=n;i++)read(ch[i][0]),read(ch[i][1]);dfs(1);dfs2(1,1);printf("%lld\n",ans);for(i=1;i<=n;i++)add(i,1);for(read(m);m--;printf("%lld\n",ans))read(x),remove(x);}return 0; }

  

總結(jié)

以上是生活随笔為你收集整理的BZOJ4855 : [Jsoi2016]轻重路径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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