题目描述:
4个操作
0 查询 u-v 的路径异或值
1 链接 u-v
2 断开 u-v
3 把 u 的权值 改为 V
题目分析:
都是LCT的最基本操作
题目链接:
Ac 代码:
#include <cstdio>
#include <iostream>
#define il inline
const int maxm=2*310000;
int n,m,val[maxm];
namespace LCT{
int top,son[maxm][2],fa[maxm],xr[maxm],stk[maxm],rev[maxm];
il void pushup(int x){xr[x]=xr[son[x][1]]^xr[son[x][0]]^val[x];}
il void pushdown(int x)
{
if(rev[x])
{
rev[son[x][1]]^=1,rev[son[x][0]]^=1,rev[x]=0;
std::swap(son[x][1],son[x][0]);
}
}
il bool isroot(int x){return (son[fa[x]][1]!=x&&son[fa[x]][0]!=x);}
void rotate(int x)
{
int fa1=fa[x],fa2=fa[fa1],l;
if(son[fa1][0]==x) l=0;
else l=1;
int r=l^1;
if(!isroot(fa1))
{
if(son[fa2][0]==fa1) son[fa2][0]=x;
else son[fa2][1]=x;
}
fa[x]=fa2;fa[fa1]=x;fa[son[x][r]]=fa1;
son[fa1][l]=son[x][r];son[x][r]=fa1;
pushup(fa1);pushup(x);
}
void splay(int x)
{
top=1;stk[top]=x;
for(int i=x;!isroot(i);i=fa[i]) stk[++top]=fa[i];
for(int i=top;i;i--) pushdown(stk[i]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if((son[y][0]==x)^(son[z][0]==y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
il void access(int x){for(int t=0;x;t=x,x=fa[x]) splay(x),son[x][1]=t,pushup(x);}//打通重路径
il void makeroot(int x){access(x),splay(x),rev[x]^=1;}//变为此Slpay的root
il int findroot(int x){access(x),splay(x);while(son[x][0])x=son[x][0];return x;}//寻找x所在树的根
il void split(int x,int y){makeroot(x);access(y);splay(y);}
il void cut(int x,int y){split(x,y);if(son[y][0]==x) son[y][0]=0,fa[x]=0;}
il void link(int x,int y){makeroot(x);fa[x]=y;}
il bool ask(int x,int y)
{
if(x==y) return 1;
return (findroot(x)==findroot(y));
}
};
int main()
{
//freopen("l.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]),LCT::xr[i]=val[i];
for(int i=1;i<=m;i++)
{
int opt,u,v;
scanf("%d%d%d",&opt,&u,&v);
if(opt==0)
{
LCT::makeroot(u),LCT::access(v),LCT::splay(v);
printf("%d\n",LCT::xr[v]);
}
if(opt==1)
{
if(LCT::ask(u,v)) continue;
LCT::link(u,v);
}
if(opt==2)
{
if(!LCT::ask(u,v)) continue;
LCT::cut(u,v);
}
if(opt==3)
{
LCT::access(u),LCT::splay(u),val[u]=v,LCT::pushup(u);
}
}
return 0;
}