1 namespace LCT{ 2 int top,son[maxn][2],fa[maxn],stk[maxn],rev[maxn],val[maxn],tag[maxn]; 3 il void pushup(int x) 4 { 5 tag[x]=x; 6 if(val[tag[x]]>val[tag[son[x][0]]]) tag[x]=tag[son[x][0]]; 7 if(val[tag[x]]>val[tag[son[x][1]]]) tag[x]=tag[son[x][1]]; 8 } //维护信息 9 il void pushdown(int x) 10 { 11 if(rev[x]) 12 { 13 rev[son[x][1]]^=1,rev[son[x][0]]^=1,rev[x]=0; 14 std::swap(son[x][1],son[x][0]); 15 } 16 } 17 il bool isroot(int x){return (son[fa[x]][1]!=x&&son[fa[x]][0]!=x);} 18 void rotate(int x) 19 { 20 int fa1=fa[x],fa2=fa[fa1],l; 21 if(son[fa1][0]==x) l=0; 22 else l=1; 23 int r=l^1; 24 if(!isroot(fa1)) 25 { 26 if(son[fa2][0]==fa1) son[fa2][0]=x; 27 else son[fa2][1]=x; 28 } 29 fa[x]=fa2;fa[fa1]=x;fa[son[x][r]]=fa1; 30 son[fa1][l]=son[x][r];son[x][r]=fa1; 31 pushup(fa1);pushup(x); 32 } 33 void splay(int x) 34 { 35 top=1;stk[top]=x; 36 for(int i=x;!isroot(i);i=fa[i]) stk[++top]=fa[i]; 37 for(int i=top;i;i--) pushdown(stk[i]); 38 while(!isroot(x)) 39 { 40 int y=fa[x],z=fa[y]; 41 if(!isroot(y)) 42 { 43 if((son[y][0]==x)^(son[z][0]==y)) rotate(x); 44 else rotate(y); 45 } 46 rotate(x); 47 } 48 } 49 il void access(int x){for(int t=0;x;t=x,x=fa[x]) splay(x),son[x][1]=t,pushup(x);}//打通重路径 50 il void makeroot(int x){access(x),splay(x),rev[x]^=1;}//变为此Splay的root 51 il int findroot(int x){access(x),splay(x);while(son[x][0])x=son[x][0];return x;}//寻找x所在树的根 52 void split(int x,int y){makeroot(x);access(y);splay(y);} //搜寻(u,v)路径信息时先split(u,v)然后路径信息会传递到y上 53 void cut(int x,int y){split(x,y);if(son[y][0]==x) son[y][0]=0,fa[x]=0;} 54 void link(int x,int y){makeroot(x);fa[x]=y;} 55 };
LCT