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 }
View Code

 

以上是关于Luogu 2147 洞穴勘测 - LCT的主要内容,如果未能解决你的问题,请参考以下文章

题解Luogu P2147 [SDOI2008]洞穴勘测

P2147 [SDOI2008]洞穴勘测

P2147 [SDOI2008]洞穴勘测

洛谷P2147 [SDOI2008]Cave 洞穴勘测

BZOJ2049:[SDOI2008]洞穴勘测——题解

洛谷 2147 SDOI2008 Cave 洞穴勘测