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板子题qvq
#include <bits/stdc++.h>
#define N 300010
#define Lc cur->ch[0]
#define Rc cur->ch[1]
#define rep(i,l,r) for (int i=l;i<=r;i++)
using namespace std;
int n,m;
struct node{
int x,s,size; bool rev;
node *ch[2],*fa,*parent;
}t[N];
template <class Aqua>
inline void read(Aqua &s){
s=0; Aqua f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) s=s*10+c-'0',c=getchar();
s*=f;
}
inline int get(node *cur){
return (cur->fa->ch[0]==cur)?0:1;
}
inline void update(node *cur){
cur->size=Lc->size+Rc->size+1;
cur->s=cur->x^Lc->s^Rc->s;
}
inline void pushdown(node *cur){
if (cur->rev){
cur->rev=0;
swap(Lc,Rc);
Lc->rev^=1,Rc->rev^=1;
}
}
void rotate(node *cur){
pushdown(cur->fa),pushdown(cur);
node *fa=cur->fa; int x=get(cur);
cur->fa=fa->fa; fa->fa->ch[get(fa)]=cur;
fa->ch[x]=cur->ch[x^1]; cur->ch[x^1]->fa=fa;
cur->ch[x^1]=fa; fa->fa=cur;
update(fa),update(cur);
cur->parent=fa->parent; fa->parent=t;
}
void splay(node *cur){
for (;cur->fa!=t;rotate(cur))
if (cur->fa->fa!=t)
rotate(get(cur)^get(cur->fa)?cur:cur->fa);
pushdown(cur);
}
void access(node *cur){
splay(cur);
Rc->fa=t;
Rc->parent=cur; Rc=t;
update(cur);
for (node *v;cur->parent!=t;cur->fa=v,cur=v){
splay(v=cur->parent);
v->ch[1]->fa=t; v->ch[1]->parent=v;
v->ch[1]=cur; update(v);
}
}
void evert(node *cur){
access(cur);
splay(cur);
cur->rev^=1;
pushdown(cur);
}
int find(node *cur){
access(cur);
splay(cur);
for (;;pushdown(cur=Lc))
if (Lc==t)
return (cur-t);
}
void link(node *u,node *v){
evert(u);
access(v);
splay(v);
u->ch[0]->fa=t; u->ch[0]->parent=u;
u->ch[0]=v; v->fa=u; update(u);
}
void cut(node *u,node *v){
evert(u);
access(v);
splay(v);
if (v->ch[0]!=u || u->size!=1)
return;
v->ch[0]=t; update(v);
u->fa=u->parent=t;
}
int query(node *u,node *v){
evert(u);
access(v);
splay(v);
return v->ch[0]->s^v->x;
}
void pre(){
node *cur=t;
cur->size=cur->rev=0;
cur->ch[0]=cur->ch[1]=cur->fa=cur->parent=t;
rep(i,1,n){
cur=t+i; read(cur->x);
cur->size=1; cur->rev=0;
cur->ch[0]=cur->ch[1]=cur->fa=cur->parent=t;
}
}
int main(){
read(n),read(m);
pre();
int opt,u,v;
rep(i,1,m){
read(opt),read(u),read(v);
if (!opt)
printf("%d\n",query(t+u,t+v));
if (opt==1)
if (find(t+u)!=find(t+v))
link(t+u,t+v);
if (opt==2)
cut(t+u,t+v);
if (opt==3)
(t+u)->x=v,splay(t+u);
}
return 0;
}