3282: Tree

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

 
总算是理解了LCT。。。splay可以维护一切可合并的操作,所以异或也可以维护。。。
然后再在splay上维护值即可。
  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 500000+5
 14 #define maxm 10000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read(){
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 27     return x*f;
 28 }
 29 int n,m,v[maxn],sum[maxn],c[maxn][2],fa[maxn],sta[maxn],top;
 30 bool rev[maxn];
 31 bool isroot(int x){
 32     return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
 33 }
 34 void pushup(int x){
 35     sum[x]=v[x]^sum[c[x][0]]^sum[c[x][1]];
 36 }
 37 void rever(int x){
 38     rev[x]^=1;
 39     swap(c[x][0],c[x][1]);
 40 }
 41 void pushdown(int x){
 42     if(!rev[x])return ;
 43     rever(c[x][0]);rever(c[x][1]);
 44     rev[x]=0;
 45 }
 46 void rotate(int x){
 47     int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
 48     if(!isroot(y))c[z][c[z][1]==y]=x;
 49     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 50     c[y][l]=c[x][r];c[x][r]=y;
 51     pushup(y);pushup(x);
 52 }
 53 void splay(int x){
 54     int top=0;sta[++top]=x;
 55     for(int y=x;!isroot(y);y=fa[y])sta[++top]=fa[y];
 56     for(;top;)pushdown(sta[top--]);
 57     while(!isroot(x)){
 58         int y=fa[x],z=fa[y];
 59         if(!isroot(y)){
 60             if(c[z][0]==y^c[y][0]==x)
 61                 rotate(x);
 62             else rotate(y);
 63         }
 64         rotate(x);
 65     }
 66 }
 67 void access(int x){
 68     for(int y=0;x;x=fa[x]){
 69         splay(x);c[x][1]=y;pushup(x);y=x;
 70     }
 71 }
 72 void makeroot(int x){
 73     access(x);splay(x);rever(x);
 74 }
 75 void split(int x,int y){
 76     makeroot(x);access(y);splay(y);
 77 }
 78 int findroot(int x){
 79     access(x);
 80     while(!isroot(x))x=fa[x];
 81     return x;
 82 }
 83 void link(int x,int y){
 84     if(findroot(x)==findroot(y))return ;
 85     makeroot(x);fa[x]=y;splay(x);
 86 }
 87 void cut(int x,int y){
 88     split(x,y);if(c[y][0]==x)c[y][0]=fa[x]=0;
 89 }
 90 int main(){
 91     //freopen("input.txt","r",stdin);
 92     //freopen("output.txt","w",stdout);
 93     n=read();m=read();
 94     for1(i,n)v[i]=sum[i]=read();
 95     while(m--){
 96         int ch=read(),x=read(),y=read();
 97         if(ch==1)link(x,y);
 98         else if(ch==2)cut(x,y);
 99         else if(ch==3)makeroot(x),v[x]=y,pushup(x);
100         else if(x==y)printf("%d\n",v[x]);
101         else split(x,y),printf("%d\n",sum[y]);
102     }
103     return 0;
104 }
View Code

 

posted @ 2016-07-11 00:10  HTWX  阅读(88)  评论(0编辑  收藏  举报