Luogu 2147 洞穴勘测 - LCT
Posted cychester
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 2147 洞穴勘测 - LCT相关的知识,希望对你有一定的参考价值。
Solution
$LCT$ 打上 $cut$ , $link$ 和 $finroot$ 即可
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rd read() 5 using namespace std; 6 7 const int N = 1e4 + 5; 8 9 int n, m; 10 11 int read() { 12 int X = 0, p = 1; char c = getchar(); 13 for (; c > ‘9‘ || c < ‘0‘; c = getchar()) 14 if (c == ‘-‘) p = -1; 15 for (; c >= ‘0‘ && c <= ‘9‘; c = getchar()) 16 X = X * 10 + c - ‘0‘; 17 return X * p; 18 } 19 20 namespace LCT { 21 int f[N], ch[N][2], tun[N]; 22 #define lc(x) ch[x][0] 23 #define rc(x) ch[x][1] 24 25 int isroot(int x) { 26 return rc(f[x]) != x && lc(f[x]) != x; 27 } 28 29 int get(int x) { 30 return rc(f[x]) == x; 31 } 32 33 void rev(int x) { 34 swap(lc(x), rc(x)); 35 tun[x] ^= 1; 36 } 37 38 void pushdown(int x) { 39 if (tun[x]) { 40 if (lc(x)) rev(lc(x)); 41 if (rc(x)) rev(rc(x)); 42 tun[x] = 0; 43 } 44 } 45 46 void pd(int x) { 47 if (!isroot(x)) 48 pd(f[x]); 49 pushdown(x); 50 } 51 52 void rotate(int x) { 53 int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1]; 54 if (!isroot(old)) ch[oldf][get(old)] = x; 55 ch[x][get(x) ^ 1] = old; 56 ch[old][get(x)] = son; 57 f[old] = x; f[x] = oldf; f[son] = old; 58 } 59 60 void splay(int x) { 61 pd(x); 62 for (; !isroot(x); rotate(x)) 63 if (!isroot(f[x])) 64 rotate(get(f[x]) == get(x) ? f[x] : x); 65 } 66 67 void access(int x) { 68 for (int y = 0; x; y = x, x = f[x]) 69 splay(x), ch[x][1] = y; 70 } 71 72 void mroot(int x) { 73 access(x); splay(x); rev(x); 74 } 75 76 int findr(int x) { 77 access(x); splay(x); 78 while(lc(x)) pushdown(x), x = lc(x); 79 return x; 80 } 81 82 void split(int x, int y) { 83 mroot(x); access(y); splay(y); 84 } 85 86 void cut(int x, int y) { 87 split(x, y); 88 f[x] = ch[y][0] = 0; 89 } 90 91 void link(int x, int y) { 92 mroot(x); 93 f[x] = y; 94 } 95 }using namespace LCT; 96 97 int main() 98 { 99 n = rd; m = rd; 100 for (; m; m--) { 101 char op[10]; 102 scanf("%s", op); 103 if (op[0] == ‘Q‘) { 104 int u = rd, v = rd; 105 mroot(u); 106 if (findr(v) != u) 107 puts("No"); 108 else puts("Yes"); 109 } 110 if (op[0] == ‘C‘) { 111 int u = rd, v = rd; 112 link(u, v); 113 } 114 if (op[0] == ‘D‘) { 115 int u = rd, v = rd; 116 cut(u, v); 117 } 118 } 119 }
以上是关于Luogu 2147 洞穴勘测 - LCT的主要内容,如果未能解决你的问题,请参考以下文章