记录编号 392989 评测结果 AAAAAAAAAA
题目名称 [SDOI 2008]Cave 洞穴勘测 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 0.894 s
提交时间 2017-04-09 17:50:45 内存使用 0.49 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <list>
#include <queue>
#include <vector>
#include <queue>
#include <deque>
#include <list>
using namespace std;
const int MAXN = 1e4+20;
int fa[MAXN], ch[MAXN][2], size[MAXN];
bool rev[MAXN];
inline int getdir(int x){
  return ch[fa[x]][1] == x;
}
inline void link(int x, int y, int d){ //把x放到y的ch[d]上
  if(x)fa[x] = y;
  if(y)ch[y][d] = x;
}
inline bool isroot(int x){
  return ch[fa[x]][getdir(x)] != x;
}
inline void reverse(int x){
  if(x){
    swap(ch[x][1], ch[x][0]);
    rev[x] ^= 1;
  }
}
inline void pushdown(int x){
  if(rev[x]){
    reverse(ch[x][0]); reverse(ch[x][1]);
    rev[x] = 0;
  }
}
inline void pushup(int x){
  size[x] = 1+size[ch[x][0]]+size[ch[x][1]];
}
void rotate(int x){
  int f = fa[x], d = getdir(x);
  fa[x] = fa[f];
  if(!isroot(f))ch[fa[f]][getdir(f)] = x;
  link(ch[x][d^1], f, d);
  link(f, x, d^1);
  pushup(f); pushup(x);
}
void clear(int x){
  if(!isroot(x))clear(fa[x]);
  pushdown(x); //也可以边splay边下推
}
inline void splay(int x){
  for(clear(x); !isroot(x); rotate(x))
    if(!isroot(fa[x]))rotate(getdir(x) == getdir(fa[x])?fa[x]:x);
}
inline void access(int x){
  for(int p = 0; x; x = fa[p = x]){
    splay(x); 
    ch[x][1] = p;
    pushup(x);
  }
}
inline void makeroot(int x){
  access(x); splay(x);
  reverse(x);
}
inline int findroot(int x){
  while(fa[x])x = fa[x];
  return x;
}
inline void link(int u, int v){
  makeroot(u); fa[u] = v;
}
inline void cut(int v){
  access(v);
  splay(v);
  ch[v][0] = fa[ch[v][0]] = 0;
  pushup(v);
}
inline bool isconnect(int u, int v){
  return findroot(u) == findroot(v);
}
int ns[MAXN];
char buf[100];
int main(){
  freopen("sdoi2008_cave.in", "r", stdin);
  freopen("sdoi2008_cave.out", "w", stdout);
  int n, m; scanf("%d %d", &n, &m);
  for(int i = 1; i <= n; i++)ns[i] = i;
  while(m--){
    scanf("%s", buf);
    int x, y; scanf("%d %d", &x, &y);
    if(buf[0] == 'Q'){
      puts(isconnect(ns[x], ns[y])?"Yes":"No");
    }else if(buf[0] == 'D'){
      makeroot(ns[x]);
      cut(ns[y]);
    }else if(buf[0] == 'C'){
      link(ns[x], ns[y]);
    }
  }
  return 0;
}