1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include <cstdio> #include <algorithm> using namespace std; const int N = 1e4 + 10; int n, m; struct Node { int tag; int p, s[2]; } tr[N]; void reverse(int x) { tr[x].tag ^= 1; swap(tr[x].s[0], tr[x].s[1]); } void pushdown(int x) { if (tr[x].tag) { reverse(tr[x].s[0]); reverse(tr[x].s[1]); tr[x].tag = 0; } } bool isroot(int x) { return tr[tr[x].p].s[0] != x && tr[tr[x].p].s[1] != x; } void rotate(int x) { int y = tr[x].p, z = tr[y].p; int k = tr[y].s[1] == x; if (!isroot(y)) tr[z].s[tr[z].s[1] == y] = x; tr[x].p = z; tr[y].s[k] = tr[x].s[k ^ 1]; tr[tr[x].s[k ^ 1]].p = y; tr[x].s[k ^ 1] = y; tr[y].p = x; } void update(int x) { if (!isroot(x)) update(tr[x].p); pushdown(x); } void splay(int x) { update(x); while (!isroot(x)) { int y = tr[x].p, z = tr[y].p; if (!isroot(y)) if ((y == tr[z].s[1]) ^ (x == tr[y].s[1])) rotate(x); else rotate(y); rotate(x); } } void access(int x) { int tmp = x; for (int y = 0; x; y = x, x = tr[x].p) { splay(x); tr[x].s[1] = y; } splay(tmp); } void makeroot(int x) { access(x); reverse(x); } int findroot(int x) { access(x); while (tr[x].s[0]) { pushdown(x); x = tr[x].s[0]; } splay(x); return x; } void split(int x, int y) { makeroot(x); access(y); } void link(int x, int y) { makeroot(x); if (findroot(y) != x) tr[x].p = y; } void cut(int x, int y) { makeroot(x); if (findroot(y) == x && tr[y].p == x && !tr[y].s[0]) tr[x].s[1] = tr[y].p = 0; } bool check(int x, int y) { makeroot(x); return findroot(y) == x; } int main() { scanf("%d%d", &n, &m); for (char op[10]; m; m--) { int x, y; scanf("%s%d%d", op, &x, &y); if (op[0] == 'Q') puts(check(x, y) ? "Yes" : "No"); else if (op[0] == 'C') link(x, y); else if (op[0] == 'D') cut(x, y); } return 0; }
|