1. 程式人生 > >bzoj 4530 [BJOI2014]大融合 (LCT)

bzoj 4530 [BJOI2014]大融合 (LCT)

show 記錄 void for char shu 負載 http pan

題目大意:給你一棵樹,樹的邊是一條一條連上去的

洛谷P4219傳送門 LOJ#2230傳送門

在連邊的過程中詢問某條邊的“負載”,即能通過這條邊的所有不同的路徑的數量

LCT動態維護當前節點的子樹大小

size記錄該節點的虛子樹的大小之和,sum記錄該節點為根節點的子樹大小

更換虛子節點時,或者連上新的虛子樹時,即access和link操作,要註意更新size

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define N 100100
 5 #define il inline 
 6
using namespace std; 7 8 int n,m,tp; 9 int stk[N]; 10 struct LinkCutTree{ 11 int fa[N],ch[N][2],rv[N],sz[N],sum[N]; 12 il int idf(int x){return ch[fa[x]][0]==x?0:1;} 13 il void con(int x,int ff,int p){fa[x]=ff,ch[ff][p]=x;} 14 il void rev(int x){swap(ch[x][0],ch[x][1]),rv[x]^=1;} 15
il int isroot(int x){return (ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x)?1:0;} 16 il void pushup(int x){sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+sz[x]+1;} 17 il void pushdown(int x) 18 { 19 if(rv[x]){ 20 if(ch[x][0]) rev(ch[x][0]); 21 if(ch[x][1]) rev(ch[x][1]); 22
rv[x]=0; 23 } 24 } 25 il void rot(int x) 26 { 27 int y=fa[x],ff=fa[y],px=idf(x),py=idf(y); 28 if(!isroot(y))ch[ff][py]=x;fa[x]=ff; 29 ch[y][px]=ch[x][px^1],fa[ch[x][px^1]]=y; 30 ch[x][px^1]=y,fa[y]=x; 31 pushup(y),pushup(x); 32 } 33 il void splay(int x) 34 { 35 int y=x;stk[++tp]=x; 36 while(!isroot(y)){stk[++tp]=fa[y],y=fa[y];} 37 while(tp){pushdown(stk[tp--]);} 38 while(!isroot(x)){y=fa[x]; 39 if(isroot(y)) rot(x); 40 else if(idf(y)==idf(x)) rot(y),rot(x); 41 else rot(x),rot(x);} 42 pushup(x); 43 } 44 il void access(int x) 45 { 46 for(int y=0;x!=0;y=x,x=fa[x]) 47 { 48 splay(x); 49 sz[x]-=sum[y]; 50 sz[x]+=sum[ch[x][1]]; 51 ch[x][1]=y,pushup(x); 52 } 53 } 54 il void mkroot(int x){access(x),splay(x),rev(x);} 55 il void split(int x,int y){mkroot(y),access(x),splay(x);} 56 il void link(int x,int y){split(x,y),fa[y]=x,sz[x]+=sum[y],pushup(x);} 57 }lct; 58 int gint() 59 { 60 int rett=0,fh=1;char c=getchar(); 61 while(c<0||c>9){if(c==-)fh=-1;c=getchar();} 62 while(c>=0&&c<=9){rett=(rett<<3)+(rett<<1)+c-0;c=getchar();} 63 return rett*fh; 64 } 65 void gchar(char str[]) 66 { 67 int num=0;char c=getchar(); 68 while(c<A||c>Z){c=getchar();} 69 while(c>=A&&c<=Z){str[num++]=c;c=getchar();} 70 str[num]=\0; 71 } 72 73 int main() 74 { 75 n=gint(),m=gint(); 76 char q[5];int x,y; 77 for(int i=1;i<=m;i++) 78 { 79 gchar(q),x=gint(),y=gint(); 80 if(q[0]==A){lct.link(x,y);} 81 if(q[0]==Q){lct.split(x,y); 82 printf("%lld\n",1ll*(lct.sum[y])*(lct.sum[x]-lct.sum[y]));} 83 } 84 return 0; 85 }

bzoj 4530 [BJOI2014]大融合 (LCT)