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 }