1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include<iostream> #include<cstdio> #define ll long long using namespace std;
const ll N=1e5;
ll n,m,op,x,y;
ll buffa[N+5],bufch[2][N+5],bufxr[N+5],bufval[N+5]; bool bufrev[N+5]; ll *nowfa=buffa,*nowch[2]={bufch[0],bufch[1]},*nowxr=bufxr,*nowval=bufval; bool *nowrev=bufrev;
struct LCT{ ll *fa,*ch[2],*xr,*val;bool *rev; inline void Init(ll x) { ch[0]=nowch[0];ch[1]=nowch[1];fa=nowfa;xr=nowxr;val=nowval;rev=nowrev; nowch[0]+=x+1;nowch[1]+=x+1;nowfa+=x+1;nowxr+=x+1;nowval+=x+1;nowrev+=x+1; } inline void Pushup(ll x) {xr[x]=xr[ch[0][x]]^xr[ch[1][x]]^val[x];} inline void Pushdown(ll x) { if(rev[x]) { rev[ch[0][x]]^=1;rev[ch[1][x]]^=1;swap(ch[0][x],ch[1][x]);rev[x]=0; } } inline ll Get(ll x) {return x==ch[1][fa[x]];} inline ll Isroot(ll x) {return ch[0][fa[x]]!=x&&ch[1][fa[x]]!=x;} inline void Update(ll x) {if(!Isroot(x)) Update(fa[x]);Pushdown(x);} inline void Rotate(ll x) { ll y=fa[x],z=fa[y],c=Get(x);if(!Isroot(y)) ch[y==ch[1][z]][z]=x; ch[c][y]=ch[c^1][x];if(ch[c^1][x]) fa[ch[c^1][x]]=y; ch[c^1][x]=y;fa[y]=x;fa[x]=z;Pushup(y);Pushup(x); } inline void splay(ll x) { Update(x); for(ll f;f=fa[x],!Isroot(x);Rotate(x)) { if(!Isroot(f)) Rotate(Get(f)==Get(x)?f:x); } } inline ll Access(ll x) { ll p=0;for(;x;p=x,x=fa[x]) {splay(x);ch[1][x]=p;Pushup(x);}return p; } inline void Makeroot(ll x) {Access(x);splay(x);rev[x]^=1;} inline ll Find(ll x) { Access(x);splay(x);Pushdown(x); while(ch[0][x]) {x=ch[0][x];Pushdown(x);}splay(x);return x; } inline void Split(ll x,ll y) {Makeroot(x);Access(y);splay(y);} inline void Link(ll x,ll y) {Makeroot(x);fa[x]=y;} inline void Cut(ll x,ll y) { Split(x,y);if(ch[0][y]==x&&ch[1][x]==0) ch[0][y]=fa[x]=0; } inline void Fix(ll x,ll y) {Access(x);splay(x);val[x]=y;Pushup(x);} }T;
inline ll read() { ll ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();} while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();} return ret*f; }
inline void write(ll x) { static char buf[22];static ll len=-1; if(x>=0) {do{buf[++len]=x%10+48;x/=10;}while(x);} else {putchar('-');do{buf[++len]=-(x%10)+48;x/=10;}while(x);} while(len>=0) putchar(buf[len--]); }
inline void writeln(ll x) {write(x);putchar('\n');}
int main() {
n=read();m=read();T.Init(n);
for(ll i=1;i<=n;i++) {T.xr[i]=T.val[i]=read();}
while(m--) { op=read();x=read();y=read(); if(op==0) {T.Split(x,y);writeln(T.xr[y]);} if(op==1) {ll xx=T.Find(x),yy=T.Find(y);if(xx!=yy) T.Link(x,y);} if(op==2) {ll xx=T.Find(x),yy=T.Find(y);if(xx==yy) T.Cut(x,y);} if(op==3) {T.Fix(x,y);} }
return 0; }
|