洞穴勘测——LCT模板
Posted wyb-----520
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洞穴勘测——LCT模板相关的知识,希望对你有一定的参考价值。
改了4小时,我果然还是太弱了……
#include<bits/stdc++.h>
using namespace std;
const int maxx=1e4+5;
int c[maxx][2],fa[maxx],Rev[maxx];
int get(int x){
if(c[fa[x]][1]==x)return 1;
if(c[fa[x]][0]==x)return 0;
return -1;
}void rot(int x){
int f=fa[x],ff=fa[f],l=get(x),r=l^1;
if(get(f)!=-1)c[ff][c[ff][1]==f]=x;
fa[c[x][r]]=f; fa[f]=x; fa[x]=ff;
c[f][l]=c[x][r]; c[x][r]=f;
}
void pushdown(int x){
if(Rev[x]){
Rev[x]=0;
swap(c[x][0],c[x][1]);
Rev[c[x][0]]^=1;
Rev[c[x][1]]^=1;
}
}
void cle(int x){if(get(x)!=-1)cle(fa[x]);pushdown(x);}
void splay(int x){
cle(x);
for(int f=fa[x];get(x)!=-1;rot(x),f=fa[x])
if(get(f)!=-1)rot(get(x)==get(f)?f:x);
}
void Access(int x){for(int t=0;x;x=fa[t=x])splay(x),c[x][1]=t;}
int Findroot(int x){//找x结点的根
Access(x);
splay(x);
while(c[x][0]){
pushdown(x);
x=c[x][0];
}
return x;
}
int Evert(int x){//反转X到根的链
Access(x);
splay(x);
Rev[x]=1;
}
void Cut(int x,int y){
Evert(x);
Access(y);
splay(y);
fa[x]=c[y][0]=0;
}
void Link(int x,int y){//让x成为y的新儿子 ,注意x是一个根
Evert(y);
fa[y]=x;
}
int main(){
char ch[20];
int x,y,n,m;
scanf("%d%d",&n,&m);
while(m--){
scanf("%s%d%d",ch,&x,&y);
if(ch[0]==‘C‘)Link(x,y);
if(ch[0]==‘D‘)Cut(x,y);
if(ch[0]==‘Q‘){
if(Findroot(x)==Findroot(y))printf("Yes
");
else printf("No
");
}
}
return 0;
}
以上是关于洞穴勘测——LCT模板的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 2049 [Sdoi2008]Cave 洞穴勘测 LCT
[LuoguP2147] [SDOI2008]洞穴勘测 (LCT维护连通性)