# bzoj2049 Cave 洞穴勘测 LCT模版

## 2049: [Sdoi2008]Cave 洞穴勘测

Time Limit: 10 Sec  Memory Limit: 259 MB

200 5
Query 123 127
Connect 123 127
Query 123 127
Destroy 127 123
Query 123 127

3 5
Connect 1 2
Connect 3 1
Query 2 3
Destroy 1 3
Query 2 3

No
Yes
No

Yes
No

## HINT

LCT裸题,但是还是调了很长时间orz

#include <cstdio>
#include <algorithm>
#define maxn 100005
using namespace std;
char opr[10];
bool rev[maxn];
int p[maxn],n,m;
int ch[maxn][2],f[maxn],stk[maxn];
int get(int x){
return ch[f[x]][1]==x;
}
void pushdown(int x){
if(rev[x]){
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
}
void rotate(int x){
int g=get(x);
int fa=f[x],ffa=f[fa];
ch[fa][g]=ch[x][g^1];
if(ch[fa][g])
f[ch[fa][g]]=fa;
f[fa]=x;
ch[x][g^1]=fa;
f[x]=ffa;
if(ffa)
ch[ffa][ch[ffa][1]==fa]=x;
return;
}
void splay(int x){
int tail=0;
for(int now=x;now;now=f[now])
stk[++tail]=now;
while(tail){
pushdown(stk[tail--]);
}
while(f[x]){
p[x]=p[f[x]];
p[f[x]]=0;
// if(f[f[x]]) rotate(get(x)==get(f[x])?f[x]:x);加上这句就会玄学RE
rotate(x);
}
}
void access(int u){
for(int v=0;u;u=p[u]){
splay(u);
f[ch[u][1]]=0;
p[ch[u][1]]=u;
ch[u][1]=v;
p[v]=0;
f[v]=u;
v=u;
}
}
int find_root(int x){
access(x);
splay(x);
while(ch[x][0]){
x=ch[x][0];
}
return x;
}
void move_root(int x){
access(x);
splay(x);
rev[x]^=1;
}
void join(int u,int v){
move_root(u);
p[u]=v;
splay(u);
}
void cut(int u,int v){
move_root(u);
access(v);
splay(v);
if(p[u]==v) p[u]=0;
else{
f[u]=0;
ch[v][ch[v][1]==u]=0;
}
}
int main(){
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%s",opr);
scanf("%d%d",&u,&v);
if(opr[0]=='C') join(u,v);
if(opr[0]=='D') cut(u,v);
if(opr[0]=='Q'){
if(find_root(u)==find_root(v)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}

posted @ 2018-08-04 20:31  AL76  阅读(44)  评论(0编辑  收藏