洛谷P3690 【模板】Link Cut Tree (动态树)
不开o2优化就要TLE,不知道为啥。
//#include <bits/stdc++.h>
#pragma GCC optimize(2)
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define debug printf("!!\n");
#define N 300005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);// freopen("in.txt","r",stdin);
using namespace std;
typedef long long ll;
typedef double db;
const int mod=1e9+7;
struct node
{
public:int fa,son[2],shu,sum;
bool Reverse;
void ini()
{
fa=son[0]=son[1]=Reverse=0;
}
}t[N];
int n,m,fa[N];
inline bool is_root(int x)
{
int fa=t[x].fa;
return (t[fa].son[0]!=x&&t[fa].son[1]!=x);
}
inline void pushreverse(int x)
{
if(!x) return ;
swap(t[x].son[0],t[x].son[1]);
t[x].Reverse^=1;
}
inline void update(int x)
{
t[x].sum=t[x].shu;
int l=t[x].son[0],r=t[x].son[1];
if(l) t[x].sum^=t[l].sum;
if(r) t[x].sum^=t[r].sum;
}
inline void pushdown(int x)
{
if(t[x].Reverse)
{
pushreverse(t[x].son[0]);
pushreverse(t[x].son[1]);
t[x].Reverse=false;
}
}
inline int get(int x)
{
return x==t[t[x].fa].son[1];
}
inline void Rotate(int x)
{
if(is_root(x)) return;
int k=get(x),fa=t[x].fa,fafa=t[fa].fa;
if(!is_root(fa)) t[fafa].son[fa==t[fafa].son[1]]=x;
t[fa].son[k]=t[x].son[k^1];
if(t[x].son[k^1]) t[t[x].son[k^1]].fa=fa;
t[x].son[k^1]=fa;
t[fa].fa=x;
t[x].fa=fafa;
update(x);
update(fa);
}
inline void push(int x)
{
if(!is_root(x)) push(t[x].fa);
pushdown(x);
}
inline void splay(int x)
{
push(x);
for(int fa;!is_root(x);Rotate(x))
{
fa=t[x].fa;
// cout<<x<<' '<<fa<<' '<<is_root(fa)<<' '<<t[0].son[0]<<' '<<t[0].son[1]<<endl;
if(!is_root(fa)) Rotate(get(x)==get(fa)?fa:x);
}
}
inline void access(int x)
{
int y=0;
do
{
splay(x);
// t[t[x].son[1]].is_root=true;
t[x].son[1]=y;
// t[y].fa=x;
update(x);
x=t[y=x].fa;
}while(x);
}
inline void mroot(int x)
{
access(x);
splay(x);
pushreverse(x);
// update(x);
}
inline int findroot(int x)
{
while(t[x].fa) x=t[x].fa;
return x;
}
inline void link(int u,int v)
{
mroot(u);
if(findroot(v)!=u)t[u].fa=v;
// update(u);
}
inline void cut(int u,int v)
{
mroot(u);
access(v);
splay(v);
if(t[v].son[0]!=u) return ;
t[u].fa=t[v].son[0]=0;
update(v);
}
int main()
{
int m;
sdd(n,m);
// fup(i,1,n)
// t[i].ini();
fup(i,1,n)
{
sd(t[i].shu);
t[i].sum=t[i].shu;
}
while(m--)
{
int f, x,y;
sddd(f,x,y);
if(!f)
{
mroot(x);
access(y);
splay(y);
update(y);
pf(t[y].sum);
}
else if(f==1)
{
link(x,y);
}
else if(f==2)
{
cut(x,y);
}
else
{
splay(x);
t[x].shu=y;
update(x);
}
}
}