3282: Tree
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 2249 Solved: 1042
[Submit][Status][Discuss]
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行,每行三个整数,分别代表操作类型和操作所需的量。
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
HINT
1<=N,M<=300000
code
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 300100; 7 8 int val[N],fa[N],ch[N][2],rev[N],sum[N],st[N],top; 9 10 inline char nc() { 11 static char buf[100000],*p1 = buf,*p2 = buf; 12 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++; 13 } 14 inline int read() { 15 int x = 0,f = 1;char ch=nc(); 16 for (; ch<‘0‘||ch>‘9‘; ch = nc()) if (ch == ‘-‘) f = -1; 17 for (; ch>=‘0‘&&ch<=‘9‘; ch = nc()) x = x*10+ch-‘0‘; 18 return x * f; 19 } 20 void pushup(int x) { 21 sum[x] = sum[ch[x][1]] ^ sum[ch[x][0]] ^ val[x]; 22 } 23 void pushdown(int x) { 24 int l = ch[x][0],r = ch[x][1]; 25 if (rev[x]) { 26 rev[l] ^= 1;rev[r] ^= 1; 27 swap(ch[x][0],ch[x][1]); 28 rev[x] ^= 1; 29 } 30 } 31 bool isroot(int x) { 32 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 33 } 34 int son(int x) { 35 return ch[fa[x]][1]==x; 36 } 37 void rotate(int x) { 38 int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b]; 39 if (!isroot(y)) ch[z][c] = x;fa[x] = z; 40 ch[x][!b] = y;fa[y] = x; 41 ch[y][b] = a;if (a) fa[a] = y; 42 pushup(y);pushup(x); 43 } 44 void splay(int x) { 45 top = 0;st[++top] = x; 46 for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i]; 47 while (top) pushdown(st[top--]); 48 while (!isroot(x)) { 49 int y = fa[x]; 50 if (!isroot(y)) { 51 if (son(x)==son(y)) rotate(y); 52 else rotate(x); 53 } 54 rotate(x); 55 } 56 } 57 void access(int x) { 58 for (int t=0; x; t=x,x=fa[x]) { 59 splay(x);ch[x][1] = t;pushup(x); 60 } 61 } 62 void makeroot(int x) { 63 access(x); 64 splay(x); 65 rev[x] ^= 1; 66 } 67 void link(int x,int y) { 68 makeroot(x); 69 fa[x] = y; 70 } 71 void cut(int x,int y) { 72 makeroot(x);access(y);splay(y); 73 ch[y][0] = fa[ch[y][0]] = 0; 74 } 75 void update(int x,int y) { 76 makeroot(x);val[x] = y;pushup(x); 77 } 78 int query(int x,int y) { 79 makeroot(x);access(y);splay(y); 80 return sum[y]; 81 } 82 int find(int x) { 83 access(x);splay(x); 84 while (ch[x][0]) x = ch[x][0]; 85 return x; 86 } 87 int main() { 88 int n = read(),m = read(),opt,x,y; 89 for (int i=1; i<=n; ++i) sum[i] = val[i] = read(); 90 while (m--) { 91 opt = read(),x = read(),y = read(); 92 if (opt==0) printf("%d\n",query(x,y)); 93 else if (opt==1) { 94 if (find(x)!=find(y)) link(x,y); 95 } 96 else if (opt==2) { 97 if (find(x)==find(y)) cut(x,y); 98 } 99 else update(x,y); 100 } 101 return 0; 102 }