裸地LCT……
开始学的时候杂七杂八的……
自己在网上看了看,感觉理解了大概的意思,又看了看yangzhe的论文,但是操作不全。。
然后是zrt讲,嗯,又有了进一步的理解。。
不过最后还是啃不知名的神犇的代码搞的。。嗯,写的很简洁。。
第一次写,基本等于照抄不会说的。。
splay炸了
#include<cstdio>
#include<algorithm>
#define N 200005
using namespace std;
struct Splaytree{
bool rev[N];
int fa[N],ls[N],rs[N],st[N],top;
void pushdown(int x){
if(!rev[x]) return;
rev[x]^=1;rev[ls[x]]^=1;rev[rs[x]]^=1;
swap(ls[x],rs[x]);
}
bool isroot(int x){
return ls[fa[x]]!=x&&rs[fa[x]]!=x;
}
void lturn(int x){
int y=fa[x],z=fa[y];
rs[y]=ls[x];fa[ls[x]]=y;
ls[x]=y;fa[y]=x;
fa[x]=z;
if(ls[z]==y) ls[z]=x;
if(rs[z]==y) rs[z]=x;
}
void rturn(int x){
int y=fa[x],z=fa[y];
ls[y]=rs[x];fa[rs[x]]=y;
rs[x]=y;fa[y]=x;
fa[x]=z;
if(rs[z]==y) rs[z]=x;
if(ls[z]==y) ls[z]=x;
}
void splay(int x){
top=0;
st[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
while(top) pushdown(st[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(isroot(y)&&ls[y]==x) rturn(x);
else if(isroot(y)&&rs[y]==x) lturn(x);
else if(ls[z]==y&&ls[y]==x) rturn(y),rturn(x);
else if(rs[z]==y&&rs[y]==x) lturn(y),lturn(x);
else if(rs[z]==y&&ls[y]==x) rturn(x),lturn(x);
else if(ls[z]==y&&rs[y]==x) lturn(x),rturn(x);
}
}
}Splay;
struct Linkcuttree{
void access(int x){
int t=0;
while(x){
Splay.splay(x);
Splay.rs[x]=t;
t=x;x=Splay.fa[x];
}
}
int findroot(int x){
access(x);Splay.splay(x);
while(Splay.ls[x]!=0) x=Splay.ls[x];
return x;
}
void makeroot(int x){
access(x);
Splay.splay(x);
Splay.rev[x]^=1;
}
void link(int x,int y){
makeroot(x);
Splay.fa[x]=y;Splay.splay(x);
}
void cut(int x,int y){
makeroot(x);
access(y);Splay.splay(y);
Splay.ls[y]=0;Splay.fa[x]=0;
}
}lct;
int n,m;
int main(){
freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y,ans;
char s[10];
scanf("%s",s);
if(s[0]=='Q'){
scanf("%d%d",&x,&y);
if(lct.findroot(x)==lct.findroot(y)) puts("Yes");
else puts("No");
}
if(s[0]=='C'){
scanf("%d%d",&x,&y);
lct.link(x,y);
}
if(s[0]=='D'){
scanf("%d%d",&x,&y);
lct.cut(x,y);
}
}
return 0;
}