# BZOJ2049：[SDOI2008]洞穴勘测——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=2049

https://www.luogu.org/problemnew/show/P2147

LCT模板题，你可以很轻松的百度出一个LCT写法教程，这里就不多言了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int N=1e4+5;
int n,m,r,fa[N],tr[N][2],rev[N],q[N];
int X=0,w=0;char ch=0;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline bool get(int x){
return tr[fa[x]][1]==x;
}
inline bool isroot(int x){
if(!fa[x])return 1;
return tr[fa[x]][0]!=x&&tr[fa[x]][1]!=x;
}
inline void pushrev(int x){
if(!rev[x])return;
swap(tr[x][0],tr[x][1]);
if(tr[x][0])rev[tr[x][0]]^=1;
if(tr[x][1])rev[tr[x][1]]^=1;
rev[x]=0;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],b=tr[y][0]==x?tr[x][1]:tr[x][0];
if(z&&!isroot(y))(tr[z][0]==y?tr[z][0]:tr[z][1])=x;
fa[x]=z;fa[y]=x;b?fa[b]=y:0;
if(tr[y][0]==x)tr[x][1]=y,tr[y][0]=b;
else tr[x][0]=y,tr[y][1]=b;
}
inline void splay(int x){
q[r=0]=x;
for(int y=x;!isroot(y);y=fa[y])q[++r]=fa[y];
for(int i=r;i>=0;i--)pushrev(q[i]);
while(!isroot(x)){
if(!isroot(fa[x]))
rotate((get(x)==get(fa[x])?fa[x]:x));
rotate(x);
}
}
inline void access(int x){
for(int y=0;x;y=x,x=fa[x]){
splay(x);tr[x][1]=y;
if(y)fa[y]=x;
}
}
inline int findroot(int x){
access(x);splay(x);
while(pushrev(x),tr[x][0])x=tr[x][0];
splay(x);
return x;
}
inline void makeroot(int x){
access(x);splay(x);
rev[x]^=1;
}
makeroot(x);fa[x]=y;
}
inline void cut(int x,int y){
makeroot(x);access(y);splay(y);
tr[y][0]=0;fa[x]=0;
}
int main(){
for(int i=1;i<=m;i++){
char ch=getchar();
while(ch<'A'||ch>'Z')ch=getchar();
if(ch=='Q'){
else puts("No");
}