_bzoj2049 [Sdoi2008]Cave 洞穴勘测【LCT】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2049
裸的LCT,保存LCT模版。说一下出bug的几个地方叭:
①,rotate时,没有判断y是否为根,这点与普通的Splay有点差别。
②,循环变量是i,而不是x!
#include <cstdio> #include <algorithm> const int maxn = 10005; int n, m, t1, t2; int ch[maxn][2], fa[maxn], stk[maxn], top; char opr[10], rev[maxn]; inline bool isroot(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; } inline void pushdown(int x) { if (rev[x]) { rev[x] = 0; rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; std::swap(ch[x][0], ch[x][1]); } } inline void rotate(int x) { int y = fa[x]; if (!isroot(y)) { if (y == ch[fa[y]][0]) { ch[fa[y]][0] = x; } else { ch[fa[y]][1] = x; } } fa[x] = fa[y]; int dir = x == ch[y][1]; ch[y][dir] = ch[x][dir ^ 1]; fa[ch[x][dir ^ 1]] = y; ch[x][dir ^ 1] = y; fa[y] = x; } inline void splay(int x) { int p; char flag1, flag2; top = 0; stk[top++] = x; for (int i = x; !isroot(i); i = fa[i]) { stk[top++] = fa[i]; } for (int i = top - 1; ~i; --i) { pushdown(stk[i]); } while (!isroot(x)) { p = fa[x]; if (isroot(p)) { rotate(x); } else { flag1 = p == ch[fa[p]][1]; flag2 = x == ch[p][1]; if (flag1 ^ flag2) { rotate(x); } else { rotate(p); } rotate(x); } } } inline void acc(int x) { int y = 0; while (x) { splay(x); ch[x][1] = y; y = x; x = fa[x]; } } inline void make_root(int x) { acc(x); splay(x); rev[x] ^= 1; } inline void link(int x, int y) { make_root(x); fa[x] = y; } inline void cutt(int x, int y) { make_root(x); acc(y); splay(y); ch[y][0] = fa[x] = 0; } inline int fnd_root(int x) { acc(x); splay(x); int i; for (i = x; ch[i][0]; i = ch[i][0]); return i; } int main(void) { //freopen("in.txt", "r", stdin); scanf("%d%d", &n, &m); while (m--) { scanf("%s%d%d", opr, &t1, &t2); if (opr[0] == 'Q') { make_root(t1); puts(fnd_root(t2) == t1? "Yes": "No"); } else if (opr[0] == 'C') { link(t1, t2); } else { cutt(t1, t2); } } return 0; }