3282: Tree(LCT)

3282: Tree

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 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

Sample Output

3
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 }

 

posted @ 2017-12-30 16:54  MJT12044  阅读(201)  评论(0编辑  收藏  举报