1. 程式人生 > >[SDOI2008]洞穴勘測

[SDOI2008]洞穴勘測

link urn AI pan play fin har span clu

SOL: LCT維護聯通性,當然,啟發式合並並查集可能會更好寫。

#include<bits/stdc++.h>
#define N 200007
int rev[N],ch[N][2],f[N],q[N],top;
using namespace std;
inline void push_down(int x) {
    if (rev[x]) {
        rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; rev[x]=0;
        swap(ch[x][0],ch[x][1]);
    }
}
inline bool
rt(int x){ return ch[f[x]][0]!=x&&ch[f[x]][1]!=x; } inline void ro(int x){ int y=f[x],z=f[y],kind=(ch[y][0]==x); if (!rt(y)) ch[z][ch[z][1]==y]=x; f[ch[x][kind]]=y; f[y]=x; f[x]=z; ch[y][kind^1]=ch[x][kind]; ch[x][kind]=y; } //inline void splay(int x){ inline void splay(int
x) { q[top=1]=x; for (int i=x;!rt(i);i=f[i]) q[++top]=f[i]; while (top) push_down(q[top--]); while (!rt(x)) { int y=f[x],z=f[y]; if (!rt(y)) { if (ch[y][0]==x^ch[z][0]==y) ro(x); else ro(y); } ro(x); } // push_up(x);
} inline void access(int x) { for (int t=0;x;t=x,x=f[x]) splay(x),ch[x][1]=t; } inline void make_rt(int x) { access(x); splay(x); rev[x]^=1; } inline void link(int x,int y){ make_rt(x); f[x]=y; } inline int find(int x){ access(x); splay(x); while (ch[x][0]) push_down(x),x=ch[x][0]; return x; } inline void cut(int x,int y){ make_rt(x); if (find(y)==x&&f[x]==y&&!ch[x][1]) f[x]=ch[y][0]=0; } int n,m,x,y; char as[19]; signed main () { // freopen("a.in","r",stdin); scanf("%d%d",&n,&m); while (m--) { scanf("%s",as); scanf("%d%d",&x,&y); if (as[0]==Q) { printf("%s\n",(find(x)^find(y))?"No":"Yes"); } else if (as[0]==C) { if (find(x)^find(y)) link(x,y); } else { if (find(x)==find(y)) cut(x,y); } } }

[SDOI2008]洞穴勘測