bzoj 2049 洞穴勘測(LCT刷題)
阿新 • • 發佈:2018-12-10
LCT 的板子。。。。
後續會講原理。。
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int son[11000][2],fa[11000]; bool rt[11000],fz[11000]; char ss[10]; void reverse(int x) { swap(son[x][0],son[x][1]); fz[x]^=1; } void pushdown(int x) { if(fz[x]) { reverse(son[x][0]); reverse(son[x][1]); fz[x]=0; } } void down(int x) { if(!rt[x])down(fa[x]); pushdown(x); } void rotate(int x) { int y=fa[x],z=fa[y]; int typ=(x==son[y][1]); son[y][typ]=son[x][typ^1],fa[son[x][typ^1]]=y; son[x][typ^1]=y,fa[y]=x;fa[x]=z; if(rt[y])rt[y]=0,rt[x]=1; else son[z][son[z][1]==y]=x; } void splay(int x) { down(x); while(!rt[x]) { int y=fa[x]; if(rt[y]) { rotate(x);return; } rotate((son[fa[x]][1]==x)==(son[fa[y]][1]==y)?x:y); rotate(x); } } void access(int x) { int y=0; while(x) { splay(x); rt[son[x][1]]=1,rt[y]=0; son[x][1]=y; y=x,x=fa[x];//完事之後鏈的狀態? } } void mtr(int x) { access(x); splay(x); reverse(x); } void link(int x,int y) { mtr(x); fa[x]=y; } void cut(int x,int y) { mtr(x); access(y); splay(x);//why還要splay son[x][1]=fa[y]=0; rt[y]=1; } bool check(int x,int y) { mtr(x); access(y); splay(x); while(!rt[y])y=fa[y]; return x==y; } int main() { int n,m,a,b; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)rt[i]=1; for(int i=1;i<=m;i++) { scanf("%s",ss);scanf("%d%d",&a,&b); if(ss[0]=='C')link(a,b); if(ss[0]=='D')cut(a,b); if(ss[0]=='Q')printf("%s\n",check(a,b)?"Yes":"No"); } return 0; }