洞穴勘测
题目链接:ybt金牌导航5-4-1 / luogu P2147
题目大意
LCT 的模板题,好像还是弱化版。
要求实现一些操作。
加一条边,删一条边,询问两点是否连通。
思路
这题好像比模板题还好做。
判断是否连通模板题也有提到,就是看它们的根是否相同。
LCT 怎么做的就看模板题吧,那个可以实现的操作比这个还多。
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct Tree {
int son[2], fa, val, lazy;
}tree[200001];
int n, m, root, tot;
int tmp[200001], x, y;
string s;
int read() {
int re = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') {
re = re * 10 + c - '0';
c = getchar();
}
return re;
}
bool is_root(int now) {
return tree[tree[now].fa].son[0] != now && tree[tree[now].fa].son[1] != now;
}
void down1(int now) {
swap(tree[now].son[0], tree[now].son[1]);
tree[now].lazy ^= 1;
}
void down(int now) {
if (tree[now].lazy && now) {
if (tree[now].son[0]) down1(tree[now].son[0]);
if (tree[now].son[1]) down1(tree[now].son[1]);
tree[now].lazy = 0;
}
}
void rotate(int now) {
int father = tree[now].fa;
int grand = tree[father].fa;
int k = (now == tree[tree[now].fa].son[0]);
int son = tree[now].son[k];
if (!is_root(father))
tree[grand].son[father == tree[tree[father].fa].son[1]] = now;
tree[now].son[k] = father;
tree[father].son[!k] = son;
tree[father].fa = now;
tree[now].fa = grand;
if (son) tree[son].fa = father;
}
void splay(int x) {
tmp[0] = 1;
tmp[1] = x;
for (int i = x; !is_root(i); i = tree[i].fa)
tmp[++tmp[0]] = tree[i].fa;
while (tmp[0]) {
down(tmp[tmp[0]]);
tmp[0]--;
}
while (!is_root(x)) {
if (!is_root(tree[x].fa)) {
rotate(((x == tree[tree[x].fa].son[1]) ^ (tree[x].fa == tree[tree[tree[x].fa].fa].son[1])) ? x : tree[x].fa);
}
rotate(x);
}
}
void access(int now) {
int son = 0;
while (now) {
splay(now);
tree[now].son[1] = son;
if (son) tree[son].fa = now;
son = now;
now = tree[now].fa;
}
}
int find_root(int now) {
access(now);
splay(now);
down(now);
while (tree[now].son[0]) {
now = tree[now].son[0];
down(now);
}
return now;
}
void make_root(int now) {
access(now);
splay(now);
down1(now);
}
void select(int x, int y) {
make_root(x);
access(y);
splay(y);
}
void link(int x, int y) {
if (find_root(y) == find_root(x)) return ;
make_root(x);
tree[x].fa = y;
}
void delete_(int x, int y) {
select(x, y);
tree[x].fa = 0;
tree[y].son[0] = 0;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
cin >> s;
scanf("%d %d", &x, &y);
if (s[0] == 'C') {
link(x, y);
}
else if (s[0] == 'D') {
delete_(x, y);
}
else if (s[0] == 'Q') {
if (find_root(x) == find_root(y)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}