# bzoj2049 LCT入门

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

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 5728  Solved: 2607
[Submit][Status][Discuss]

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，弄了几天。。。终于理解了。。。

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,m;
char op[30];int u,v;
int pre[maxn],ch[maxn][2],rev[maxn];

bool isroot(int x)
{
return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x;
}

void update_rev(int x)
{
if(!x) return;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}

void up(int x)
{

}

void down(int x)
{
if(rev[x]){
update_rev(ch[x][0]);
update_rev(ch[x][1]);
rev[x]=0;
}
}

void Pd(int x)
{
if(!isroot(x)) Pd(pre[x]);
down(x);
}

void rot(int x,int kind)
{
int y=pre[x];
ch[y][kind^1]=ch[x][kind];
pre[ch[x][kind]]=y;
if(!isroot(y)) ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
up(y);
}

void splay(int x)
{
Pd(x);
while(!isroot(x)){
if(isroot(pre[x])) rot(x,ch[pre[x]][0]==x);
else{
int y=pre[x],z=pre[y];
int kind=ch[y][0]==x,one=0;
if(ch[y][0]==x&&ch[z][0]==y) one=1;
if(ch[y][1]==x&&ch[z][1]==y) one=1;
if(one) rot(y,kind),rot(x,kind);
else rot(x,kind),rot(x,kind^1);
}
}
up(x);
}

int access(int x)
{
int t=0;
while(x){
splay(x);
ch[x][1]=t;
t=x;
x=pre[x];
up(t);
}
return t;
}

int findroot(int x)
{
access(x);
splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}

void makeroot(int x)
{
access(x);
splay(x);
update_rev(x);
}

{
makeroot(x);
pre[x]=y;
splay(x);
}

void cut(int x,int y)
{
makeroot(x);
access(y);
splay(y);
ch[y][0]=pre[x]=0;
up(y);
}

void Init()
{
REP(i,0,n) pre[i]=rev[i]=ch[i][0]=ch[i][1]=0;
}

int main()
{
freopen("in.txt","r",stdin);
while(cin>>n>>m){
Init();
REP(i,1,m){
scanf("%s%d%d",op,&u,&v);
}