洞穴勘測——LCT模板
阿新 • • 發佈:2018-12-15
改了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\n"); else printf("No\n"); } } return 0; }