BZOJ4530 BJOI 2014 大融合
对LCT子树大小进行维护。
size表示实子树大小,sz表示虚子树大小。
具体操作是体现在link和splay中,可以看代码。
注意每次做完都要update。
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+10; 4 int fa[N],ma[N],pos[N],c[N][2],rev[N],s[N],n,m,q,size[N],sz[N]; 5 bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} 6 void update(int x) 7 { 8 size[x]=size[c[x][0]]+size[c[x][1]]+1+sz[x]; 9 } 10 void pushup(int x) 11 { 12 if(rev[x]) 13 { 14 rev[x]^=1;rev[c[x][0]]^=1;rev[c[x][1]]^=1; 15 swap(c[x][0],c[x][1]); 16 } 17 } 18 void rotate(int x) 19 { 20 int y=fa[x],z=fa[y],l,r; 21 l=c[y][1]==x;r=l^1; 22 if(!isroot(y))c[z][c[z][1]==y]=x; 23 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 24 c[y][l]=c[x][r];c[x][r]=y; 25 update(y);update(x); 26 } 27 void splay(int x) 28 { 29 int top=0,i; 30 for(i=x;!isroot(i);i=fa[i])s[++top]=i;s[++top]=i; 31 for(;top;top--)pushup(s[top]); 32 while(!isroot(x)) 33 { 34 int y=fa[x],z=fa[y]; 35 if(!isroot(y)) 36 { 37 if(c[y][0]==x^c[z][0]==y)rotate(x); 38 else rotate(y); 39 } 40 rotate(x); 41 } 42 return; 43 } 44 void access(int x) 45 { 46 int y=0; 47 while(x) 48 { 49 splay(x); 50 sz[x]=sz[x]-size[y]+size[c[x][1]]; 51 c[x][1]=y; 52 update(x); 53 y=x;x=fa[x]; 54 } 55 } 56 void mroot(int x) 57 { 58 access(x);splay(x);rev[x]^=1; 59 } 60 void link(int x,int y) 61 { 62 mroot(x);mroot(y); 63 sz[y]+=size[x]; 64 update(y); 65 fa[x]=y; 66 splay(x); 67 } 68 int main() 69 { 70 scanf("%d%d",&n,&q);long long ans; 71 for(int i=1;i<=n;++i)size[i]=1;int x,y; 72 for(int i=1;i<=q;++i) 73 { 74 scanf("%s%d%d",s,&x,&y); 75 if(s[0]=='A')link(x,y); 76 else 77 { 78 mroot(x);access(y); 79 ans=sz[y]+1; 80 mroot(y);access(x); 81 ans*=(sz[x]+1); 82 printf("%lld\n",ans); 83 } 84 } 85 return 0; 86 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。