洛谷 P3950 部落冲突

link-cut tree 板子题

这道题可以用来作为link-cut tree的练手题

C操作:把发生战争的俩部落的连边cut掉

U操作:把停战的俩部落link起来

Q操作:如果p部落和q部落在一棵树里(树根相同),就输出”Yes”,否则输出”No”

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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <bits/stdc++.h>
using namespace std;
const int MaxN = 300010;
int n, m, val[MaxN], p[MaxN], q[MaxN], war;
struct Link_Cut_Tree
{
int top, ch[MaxN][2], fa[MaxN], sum[MaxN], q[MaxN], rev[MaxN];
inline void pushup(int x) { sum[x] = sum[ch[x][0]] ^ sum[ch[x][1]] ^ val[x]; }
inline void pushdown(int x)
{
int l = ch[x][0], r = ch[x][1];
if (rev[x])
{
rev[l] ^= 1;
rev[r] ^= 1;
rev[x] ^= 1;
swap(ch[x][0], ch[x][1]);
}
}
inline bool isroot(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
void rotate(int x)
{
int y = fa[x], z = fa[y], l, r;
if (ch[y][0] == x)
l = 0;
else
l = 1;
r = l ^ 1;
if (!isroot(y))
{
if (ch[z][0] == y)
ch[z][0] = x;
else
ch[z][1] = x;
}
fa[x] = z;
fa[y] = x;
fa[ch[x][r]] = y;
ch[y][l] = ch[x][r], ch[x][r] = y;
pushup(y), pushup(x);
}
void splay(int x)
{
top = 1;
q[top] = x;
for (int i = x; !isroot(i); i = fa[i])
q[++top] = fa[i];
for (int i = top; i; i--)
pushdown(q[i]);
while (!isroot(x))
{
int y = fa[x], z = fa[y];
if (!isroot(y))
{
if ((ch[y][0] == x) ^ (ch[z][0] == y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
}
void access(int x)
{
for (int t = 0; x; t = x, x = fa[x])
splay(x), ch[x][1] = t, pushup(x);
}
void makeroot(int x)
{
access(x);
splay(x);
rev[x] ^= 1;
}
int find(int x)
{
access(x);
splay(x);
while (ch[x][0])
x = ch[x][0];
return x;
}
void split(int x, int y)
{
makeroot(x);
access(y);
splay(y);
}
void cut(int x, int y)
{
makeroot(x);
if (find(y) != x || fa[x] != y || ch[x][1])
return;
fa[x] = ch[y][0] = 0;
pushup(y);
}
void link(int x, int y)
{
makeroot(x);
fa[x] = y;
}
} t;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
t.link(u, v);
}
for(int i = 1; i <= m; i++)
{
std::string op;
std::cin >> op;
if(op == "Q")
{
int x, y;
scanf("%d%d", &x, &y);
int fx = t.find(x), fy = t.find(y);
if(fx == fy)
printf("Yes\n");
else printf("No\n");
}
else if(op == "C")
{
++war;
scanf("%d%d", &p[war], &q[war]);
t.cut(p[war], q[war]);
}
else
{
int x;
scanf("%d", &x);
t.link(p[x], q[x]);
}
}
return 0;
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×