3282. Tree【LCT】

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

Sample Output

3
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\n",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 }
posted @ 2018-03-31 07:20  Refun  阅读(189)  评论(0编辑  收藏  举报