[Bzoj2049][Sdoi2008]Cave 洞穴勘测
一道思路蛮清晰的题,题目有连边,删边,判断两点是否联通三个操作,因为题目中提到了“任意时刻任意两个洞穴之间至多只有一条路径”这一句话。所以在任意时刻,这些联通块都是树形的。所以不是很像splay森林LCT吗。
所以就是LCT板子了......
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 10010; 4 typedef long long ll; 5 int fa[maxn], ch[maxn][2], siz[maxn], val[maxn], lazy[maxn], st[maxn]; 6 inline bool isroot(int x) { 7 return ch[fa[x]][0] != x && ch[fa[x]][1] != x; 8 } 9 inline void pushup(int x) { 10 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; 11 } 12 inline void pushdown(int x) { 13 if (lazy[x]) { 14 if (ch[x][0])lazy[ch[x][0]] ^= 1; 15 if (ch[x][1])lazy[ch[x][1]] ^= 1; 16 swap(ch[x][0], ch[x][1]); 17 lazy[x] = 0; 18 } 19 } 20 inline void rotate(int x) { 21 int y = fa[x], z = fa[y]; 22 int k = ch[y][1] == x; 23 if (!isroot(y)) 24 ch[z][ch[z][1] == y] = x; 25 fa[x] = z; ch[y][k] = ch[x][k ^ 1]; fa[ch[x][k ^ 1]] = y; 26 ch[x][k ^ 1] = y; fa[y] = x; 27 pushup(y); pushup(x); 28 } 29 inline void splay(int x) { 30 int f = x, len = 0; 31 st[++len] = f; 32 while (!isroot(f))st[++len] = f = fa[f]; 33 while (len)pushdown(st[len--]); 34 while (!isroot(x)) { 35 int y = fa[x]; 36 int z = fa[y]; 37 if (!isroot(y)) 38 rotate((ch[y][0] == x) ^ (ch[z][0] == y) ? x : y); 39 rotate(x); 40 } 41 pushup(x); 42 } 43 inline void access(int x) { 44 for (int y = 0; x; x = fa[y = x]) 45 splay(x), ch[x][1] = y, pushup(x); 46 } 47 inline void makeroot(int x) { 48 access(x); splay(x); lazy[x] ^= 1; 49 } 50 int Findroot(int x) { 51 access(x), splay(x); 52 while (ch[x][0]) 53 pushdown(x), x = ch[x][0]; 54 splay(x); 55 return x; 56 } 57 inline void split(int x, int y) { 58 makeroot(x); access(y); splay(y); 59 } 60 inline void Link(int x, int y) { 61 makeroot(x); fa[x] = y; 62 } 63 inline void Cut(int x, int y) { 64 split(x, y); fa[x] = ch[y][0] = 0; pushup(y); 65 } 66 char s[15]; 67 int main() { 68 int n, m, x, y; 69 scanf("%d%d", &n, &m); 70 for (int i = 1; i <= m; i++) { 71 scanf("%s%d%d", s, &x, &y); 72 if (s[0] == 'C') 73 Link(x, y); 74 else if (s[0] == 'D') 75 Cut(x, y); 76 else { 77 if (Findroot(x) == Findroot(y))printf("Yes\n"); 78 else printf("No\n"); 79 } 80 } 81 }