怎麼說呢,照著打一遍就自然理解了,再打一遍就會背了,再打一遍就會推了。
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int maxn=3E5+5; 5 int fa[maxn],son[maxn][2],val[maxn],ans[maxn],n,m,opt,x,y,z; 6 bool tag[maxn]; 7 bool notroot(int x){return son[fa[x]][0]==x||son[fa[x]][1]==x;} 8 void update(int x){ans[x]=ans[son[x][0]]^ans[son[x][1]]^val[x];} 9 void pushr(int x) 10 { 11 swap(son[x][0],son[x][1]); 12 tag[x]^=1; 13 } 14 void pushdown(int x) 15 { 16 if(tag[x]) 17 { 18 if(son[x][0])pushr(son[x][0]); 19 if(son[x][1])pushr(son[x][1]); 20 tag[x]=0; 21 } 22 } 23 void rotate(int x,int c) 24 { 25 int y=fa[x]; 26 fa[x]=fa[y]; 27 son[y][!c]=son[x][c]; 28 if(son[x][c])fa[son[x][c]]=y; 29 if(notroot(y)&&son[fa[y]][0]==y)son[fa[y]][0]=x; 30 else if(notroot(y))son[fa[y]][1]=x; 31 son[x][c]=y; 32 fa[y]=x; 33 update(y); 34 update(x); 35 } 36 void down(int x) 37 { 38 if(!notroot(x)){pushdown(x);return;} 39 down(fa[x]); 40 pushdown(x); 41 } 42 void splay(int x) 43 { 44 down(x); 45 while(true) 46 { 47 int y=fa[x]; 48 if(!notroot(x))break; 49 if(!notroot(y)) 50 { 51 if(son[y][0]==x)rotate(x,1); 52 else rotate(x,0); 53 break; 54 } 55 if(son[fa[y]][0]==y) 56 { 57 if(son[y][0]==x)rotate(y,1),rotate(x,1); 58 else rotate(x,0),rotate(x,1); 59 } 60 else 61 { 62 if(son[y][1]==x)rotate(y,0),rotate(x,0); 63 else rotate(x,1),rotate(x,0); 64 } 65 } 66 } 67 void access(int x) 68 { 69 for(int y=0;x;y=x,x=fa[x]) 70 splay(x),son[x][1]=y,update(x); 71 } 72 void makeroot(int x) 73 { 74 access(x); 75 splay(x); 76 pushr(x); 77 } 78 int findroot(int x) 79 { 80 access(x); 81 splay(x); 82 while(son[x][0])pushdown(x),x=son[x][0]; 83 splay(x); 84 return x; 85 } 86 void split(int x,int y) 87 { 88 makeroot(x); 89 access(y); 90 splay(y); 91 } 92 void link(int x,int y) 93 { 94 makeroot(x); 95 if(findroot(y)!=x)fa[x]=y; 96 } 97 void cut(int x,int y) 98 { 99 makeroot(x); 100 if(findroot(y)==x&&fa[y]==x&&!son[y][0]) 101 { 102 fa[y]=son[x][1]=0; 103 update(x); 104 update(y); 105 } 106 } 107 int main() 108 { 109 ios::sync_with_stdio(false); 110 cin>>n>>m; 111 for(int i=1;i<=n;++i)cin>>val[i]; 112 while(m--) 113 { 114 cin>>opt>>x>>y; 115 if(opt==0) 116 { 117 split(x,y); 118 cout<<ans[y]<<endl; 119 } 120 else if(opt==1)link(x,y); 121 else if(opt==2)cut(x,y); 122 else 123 { 124 splay(x); 125 val[x]=y; 126 } 127 } 128 return 0; 129 }