数组,至少目前我只写数组,不写指针。
LCT这种东西我不打算讲或者什么乱七八糟的,反正这一篇是自用。
同样,看这篇博客的人可以先去别的地方学LCT,然后来我这扒代码。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ls son[x][0]
#define rs son[x][1]
#define is(x) (x==son[fa[x]][1])
#define isroot(x) (x!=son[fa[x]][0]&&x!=son[fa[x]][1])
#define N 10010
#define inf 0x3f3f3f3f
using namespace std;
int pos[N],n,m;
char ttt[10];
struct LCT
{
int son[N][2],fa[N],cnt;
bool flag[N];
int stack[N],top;
void joint(int x,int y,int d){fa[x]=y,son[y][d]=x;}
void reverse(int x)
{
flag[x]^=1;
swap(ls,rs);
}
void pushdown(int x)
{
if(flag[x])
{
reverse(x);
flag[ls]^=1,flag[rs]^=1;
flag[0]=0;
}
}
int newnode()
{
cnt++;
son[cnt][0]=son[cnt][1]=fa[cnt]=0;
return cnt;
}
void pushpath(int x)
{
for(top=0;!isroot(x);x=fa[x])stack[++top]=x;
stack[++top]=x;
for(int i=top;i;i--)pushdown(stack[i]);
}
void rotate(int x)
{
int y=fa[x],z=fa[y],i=is(x),t=son[x][!i];
if(!isroot(y))joint(x,z,is(y));
else fa[x]=z;
joint(t,y,i),joint(y,x,!i);
fa[0]=son[0][0]=son[0][1]=0;
}
void splay(int x)
{
pushpath(x);
int y,z;
while(!isroot(x))
{
y=fa[x],z=fa[y];
if(isroot(y)){rotate(x);break;}
rotate(is(x)==is(y)?y:x),rotate(x);
}
}
void access(int x)
{
int p=0;
while(x)
{
splay(x);
rs=p,p=x,x=fa[x];
}
}
void makeroot(int x)
{
access(x);
splay(x);
flag[x]=1;
pushdown(x);
}
void link(int x,int y)
{
makeroot(x);
fa[x]=y;
}
void cut(int x,int y)
{
makeroot(y);
access(x);
splay(x);
ls=fa[y]=0;
}
int findroot(int x)
{
while(fa[x])x=fa[x];
return x;
}
}lct;
int main()
{
// freopen("test.in","r",stdin);
int i,a,b;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)pos[i]=lct.newnode();
for(i=1;i<=m;i++)
{
scanf("%s",ttt);
scanf("%d%d",&a,&b);
if(ttt[0]=='C')lct.link(pos[a],pos[b]);
else if(ttt[0]=='D')lct.cut(pos[a],pos[b]);
else
{
if(lct.findroot(pos[a])==lct.findroot(pos[b]))puts("Yes");
else puts("No");
}
}
return 0;
}