LCT笔记
先存个代码
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 using namespace std;
6 struct LinkCutTree{
7 struct node{
8 int fa,son[2],rev,sum;
9 }t[500001];
10 int top,st[500001],v[500001];
11 int lr(int u){
12 return t[t[u].fa].son[1]==u;
13 }
14 bool ntrt(int u){
15 return t[t[u].fa].son[0]==u||t[t[u].fa].son[1]==u;
16 }
17 void pushup(int u){
18 t[u].sum=t[t[u].son[0]].sum^t[t[u].son[1]].sum^v[u];
19 }
20 void getrev(int u){
21 swap(t[u].son[0],t[u].son[1]);
22 t[u].rev^=1;
23 }
24 void pd(int u){
25 if(t[u].rev){
26 if(t[u].son[0])getrev(t[u].son[0]);
27 if(t[u].son[1])getrev(t[u].son[1]);
28 t[u].rev=0;
29 }
30 }
31 void rotate(int u){
32 int p=t[u].fa,pp=t[p].fa,ch=lr(u);
33 if(ntrt(p))t[pp].son[t[pp].son[1]==p]=u;
34 t[p].son[ch]=t[u].son[ch^1];
35 t[t[p].son[ch]].fa=p;
36 t[p].fa=u;
37 t[u].son[ch^1]=p;
38 t[u].fa=pp;
39 pushup(p);
40 pushup(u);
41 }
42 void splay(int u){
43 int now=u;
44 top=0;
45 st[++top]=now;
46 while(ntrt(now))st[++top]=now=t[now].fa;
47 while(top)pd(st[top--]);
48 while(ntrt(u)){
49 int f=t[u].fa,ff=t[f].fa;
50 if(ntrt(f)){
51 rotate((!lr(u))^(!lr(f))?u:f);
52 }
53 rotate(u);
54 }
55 pushup(u);
56 }
57 void access(int u){
58 for(int now=0;u;now=u,u=t[u].fa){
59 splay(u);
60 t[u].son[1]=now;
61 pushup(u);
62 }
63 }
64 void makert(int u){
65 access(u);
66 splay(u);
67 getrev(u);
68 }
69 int findrt(int u){
70 access(u);
71 splay(u);
72 while(t[u].son[0]){
73 pd(u);
74 u=t[u].son[0];
75 }
76 return u;
77 }
78 void split(int x,int y){
79 makert(x);
80 access(y);
81 splay(y);
82 }
83 void link(int x,int y){
84 makert(x);
85 if(findrt(y)!=x)t[x].fa=y;
86 }
87 void cut(int x,int y){
88 split(x,y);
89 if(findrt(y)==x&&t[x].fa==y&&!t[x].son[1]){
90 t[x].fa=t[y].son[0]=0;
91 pushup(y);
92 }
93 }
94 }lct;
95 int n,m,op,u,v;
96 int main(){
97 scanf("%d%d",&n,&m);
98 for(int i=1;i<=n;i++){
99 scanf("%d",&lct.v[i]);
100 }
101 for(int i=1;i<=m;i++){
102 scanf("%d%d%d",&op,&u,&v);
103 switch(op){
104 case 0:lct.split(u,v);printf("%d\n",lct.t[v].sum);break;
105 case 1:lct.link(u,v);break;
106 case 2:lct.cut(u,v);break;
107 case 3:lct.splay(u);lct.v[u]=v;break;
108 }
109 }
110 return 0;
111 }