【数据结构】——LCT(link cut tree)

https://www.luogu.org/problem/P3690

一道板子题。

  1 #include<cstdio>
  2 #include<string>
  3 using namespace std;
  4 #define ls c[o][0]
  5 #define rs c[o][1]
  6 #define f(i,a,b) for(int i=a;i<=b;i++)
  7 const int N=3e5+10;
  8 int n,m,c[N][2];
  9 int a[N],f[N],s[N],r[N],st[N];
 10 void pushr(int o){
 11     swap(ls,rs);
 12     r[o]^=1;
 13 }
 14 void pushdown(int o){
 15     if(r[o]){
 16         if(ls) pushr(ls);
 17         if(rs) pushr(rs);
 18         r[o]=0;
 19     }
 20 }
 21 void pushup(int o){
 22     pushdown(ls),pushdown(rs);
 23     s[o]=s[ls]^s[rs]^a[o];
 24 }
 25 bool nroot(int o){
 26     return c[f[o]][0]==o||c[f[o]][1]==o;
 27 }
 28 void rotate(int o){
 29     int y=f[o],z=f[y],k=c[y][1]==o,w=c[o][k^1];
 30     if(nroot(y)) c[z][c[z][1]==y]=o;
 31     c[o][k^1]=y;
 32     c[y][k]=w;
 33     if(w) f[w]=y;f[y]=o,f[o]=z;
 34     pushup(y);
 35 }
 36 void splay(int o){
 37     int y=o,z=0;
 38     st[++z]=y;
 39     while(nroot(y)) st[++z]=y=f[y];
 40     while(z) pushdown(st[z--]);
 41     while(nroot(o)){
 42         y=f[o],z=f[y];
 43         if(nroot(y)) rotate((c[z][0]==y)^(c[y][0]==o)?o:y);
 44         rotate(o);
 45     }
 46     pushup(o);
 47 }
 48 void access(int o){
 49     for(int y=0;o;o=f[y=o]){
 50         splay(o);
 51         rs=y;
 52         pushup(o);
 53     } 
 54 }
 55 int findrt(int o){
 56     access(o),splay(o);
 57     while(ls) pushdown(o),o=ls;
 58     splay(o);
 59     return o;    
 60 }
 61 void makert(int o){
 62     access(o),splay(o),pushr(o);
 63 }
 64 void cut(int x,int y){
 65     makert(x);
 66     if(findrt(y)==x&&f[y]==x&&!c[y][0]){
 67         f[y]=c[x][1]=0;
 68         pushup(x);    
 69     } 
 70 }
 71 void split(int x,int y){
 72     makert(x),access(y),splay(y);
 73 }
 74 void link(int x,int y){
 75     makert(x);
 76     if(findrt(y)!=x) f[x]=y;
 77 }
 78 int main(){
 79     int k,x,y;
 80     scanf("%d%d",&n,&m);
 81     f(i,1,n) scanf("%d",&a[i]);
 82     f(i,1,m){
 83         scanf("%d%d%d",&k,&x,&y);
 84         switch(k){
 85             case 0:{
 86                 split(x,y);
 87                 printf("%d\n",s[y]);
 88                 break;
 89             }
 90             case 1:{
 91                 link(x,y);
 92                 break;
 93             }
 94             case 2:{
 95                 cut(x,y);
 96                 break;
 97             }
 98             case 3:{
 99                 splay(x);
100                 a[x]=y;
101                 break;
102             }
103         }
104     }
105     return 0;
106 }
——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
原文地址:https://www.cnblogs.com/Nelson992770019/p/11305786.html