Description
给定N个点以及每个点的权值,要你处理接下来的M个操作。
操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。
保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
1<=N,M<=300000
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
1
还是LCT模板题(话说我怎么天天做板子题)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (300000+100) 5 using namespace std; 6 int Father[N],Son[N][2],Rev[N],Val[N],Xor[N]; 7 int n,m; 8 9 void Update(int x){Xor[x]=Val[x]^Xor[Son[x][0]]^Xor[Son[x][1]];} 10 int Get(int x) {return Son[Father[x]][1]==x;} 11 int Is_root(int x) {return Son[Father[x]][0]!=x && Son[Father[x]][1]!=x;} 12 13 void Rotate(int x) 14 { 15 int wh=Get(x); 16 int fa=Father[x],fafa=Father[fa]; 17 if (!Is_root(fa)) Son[fafa][Son[fafa][1]==fa]=x; 18 Father[fa]=x; 19 Son[fa][wh]=Son[x][wh^1]; 20 if (Son[fa][wh]) Father[Son[fa][wh]]=fa; 21 Father[x]=fafa; 22 Son[x][wh^1]=fa; 23 Update(fa); 24 Update(x); 25 } 26 27 void Pushdown(int x) 28 { 29 if (Rev[x] && x) 30 { 31 if (Son[x][0]) Rev[Son[x][0]]^=1; 32 if (Son[x][1]) Rev[Son[x][1]]^=1; 33 swap(Son[x][1],Son[x][0]); 34 Rev[x]=0; 35 } 36 } 37 38 int Push(int x) 39 { 40 if (!Is_root(x)) Push(Father[x]); 41 Pushdown(x); 42 } 43 44 void Splay(int x) 45 { 46 Push(x); 47 for (int fa; !Is_root(x); Rotate(x)) 48 if (!Is_root(fa=Father[x])) 49 Rotate(Get(fa)==Get(x)?fa:x); 50 } 51 52 void Access(int x) {for (int y=0;x;y=x,x=Father[x]) Splay(x),Son[x][1]=y,Update(x);} 53 int Find_root(int x) {Access(x); Splay(x); while (Son[x][0]) x=Son[x][0]; return x;} 54 void Make_root(int x) {Access(x); Splay(x); Rev[x]^=1;} 55 void Link(int x,int y) {Make_root(x); Father[x]=y;} 56 void Cut(int x,int y) {Make_root(x); Access(y); Splay(y); Son[y][0]=Father[x]=0;} 57 void Query(int x,int y){Make_root(x);Access(y); Splay(y); printf("%d ",Xor[y]);} 58 59 int main() 60 { 61 int opt,x,y; 62 scanf("%d%d",&n,&m); 63 for (int i=1; i<=n; ++i) 64 scanf("%d",&Val[i]),Xor[i]=Val[i]; 65 for (int i=1; i<=m; ++i) 66 { 67 scanf("%d%d%d",&opt,&x,&y); 68 if (opt==0) Query(x,y); 69 if (opt==1 && Find_root(x)!=Find_root(y)) Link(x,y); 70 if (opt==2 && Find_root(x)==Find_root(y)) Cut(x,y); 71 if (opt==3) Access(x),Splay(x),Val[x]=y,Update(x); 72 } 73 }