题目大意:动态树,要求link,cut,查询两点连通性
题解:LCT,对于query操作,查询x在原树的根就好了。并查集乱搞能过……
我的收获:LCTget
#include <iostream>
#include <cstdio>
#define M 100005
using namespace std;
int n,m,y;
int fa[M],c[M][2],st[M];
bool rev[M];
inline bool f(int x){return c[fa[x]][1]==x;}
inline bool isr(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void pushdown(int x)
{
if(!rev[x]) return ;
int &l=c[x][0],&r=c[x][1];
rev[l]^=1;rev[r]^=1;swap(l,r);
rev[x]=0;
}
void rotate(int x)
{
int p=fa[x],g=fa[p],r;
bool k=f(x),m=f(p);r=c[x][k^1];
if(!isr(p)) c[g][m]=x;
fa[x]=g,c[x][k^1]=p;
fa[p]=x,c[p][k]=r;
if(r) fa[r]=p;
}
void maintain(int x)
{
int top=0;st[++top]=x;
for(int i=x;!isr(i);i=fa[i]) st[++top]=fa[i];
for(int i=top;i;i--) pushdown(st[i]);
}
void splay(int x)
{
maintain(x);
for(;!isr(x);rotate(x))
if(!isr(fa[x])) rotate(f(x)==f(fa[x])?fa[x]:x);
}
void access(int x){for(y=0;x;c[x][1]=y,y=x,x=fa[x]) splay(x);}//取出当前点到当前根的这一段路径,将它们放到一个Splay中。
void rever(int x){access(x);splay(x);rev[x]^=1;}//将x旋转到其所在树的树根
void link(int x,int y){rever(y);fa[y]=x;}//将y连到x的下面
void cut(int x,int y){rever(x);access(y);splay(y);fa[x]=c[y][0]=0;}//断开x和y之间的边
int fdrt(int x)//找x在原树中的根结点
{
access(x);splay(x);
for(y=x;c[y][0];y=c[y][0]);
return y;
}
void work()
{
int x,y;
char opt[10];
while(m--)
{
scanf("%s",opt);
scanf("%d%d",&x,&y);
if(opt[0]=='C')link(x,y);
else if(opt[0]=='D')cut(x,y);
else puts(fdrt(x)==fdrt(y)?"Yes":"No");
}
}
void init(){
cin>>n>>m;
}
int main()
{
init();
work();
return 0;
}
HOME Back