BZOJ 2049: [Sdoi2008]Cave 洞穴勘测(lct)

传送门

解题思路

  板子题\(WA\)了三次。。我在丢人。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;
const int MAXN = 10005;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return f?x:-x;
}

int n,m,ch[MAXN][2],fa[MAXN];
bool tag[MAXN];

inline bool isroot(int x){
    return (x!=ch[fa[x]][0] && x!=ch[fa[x]][1]);
}

inline bool check(int x){
    return (x==ch[fa[x]][1]);
}

inline void pushdown(int x){
    if(tag[x]){
        tag[x]^=1;swap(ch[x][0],ch[x][1]);
        if(ch[x][0]) tag[ch[x][0]]^=1;
        if(ch[x][1]) tag[ch[x][1]]^=1;
    }
}

void pd(int x){
    if(!isroot(x)) pd(fa[x]);pushdown(x);
}

inline void rotate(int x){
    int y=fa[x],z=fa[y];bool chk=check(x);
    if(!isroot(y)) ch[z][check(y)]=x;
    ch[y][chk]=ch[x][chk^1];fa[ch[x][chk^1]]=y;
    ch[x][chk^1]=y;fa[y]=x;fa[x]=z;
}

inline void splay(int x){
    pd(x);
    for(;!isroot(x);rotate(x))
        if(!isroot(fa[x])) rotate(check(fa[x])==check(x)?fa[x]:x);
}

inline void access(int x){
    for(int y=0;x;y=x,x=fa[x]) {
        splay(x);ch[x][1]=y;
    }
}

inline int findroot(int x){
    access(x);splay(x);
    while(ch[x][0]) x=ch[x][0];
    return x;
}

inline void makeroot(int x){
    access(x);splay(x);tag[x]^=1;
}

inline void link(int x,int y){
    makeroot(x);fa[x]=y;
}

inline void cut(int x,int y){
    makeroot(x);access(y);splay(y);
    fa[x]=0;ch[y][0]=0;
}

int main(){
    n=rd(),m=rd();char s[10];int x,y;
    while(m--){
        scanf("%s",s+1);x=rd(),y=rd();
        if(s[1]=='Q') puts(findroot(x)==findroot(y)?"Yes":"No");
        if(s[1]=='C') link(x,y);
        if(s[1]=='D') cut(x,y);
    }
    return 0;
}
posted @ 2018-11-29 20:18  Monster_Qi  阅读(...)  评论(... 编辑 收藏