CF176E Archaeology
https://www.luogu.com.cn/problem/CF176E
非常重要的一个trick,我竟然不知道
首先把关键点拿出来,按照\(dfs\)序排后为
\(x_1,x_2,x_3,x_4,....,x_k\)
最小联通块大小\(=\frac{1}{2}*(dis(x_1,x_2)+dis(x_2,x_3)+dis(x_3,x_4)+...+dis(x_k,x_1))\)
知道这个之后就可以用set简单维护了
code:
#include<bits/stdc++.h>
#define N 200050
#define ll long long
#define pii pair<int, int>
#define fi first
#define se second
using namespace std;
struct edge {
int v, nxt, c;
} e[N << 1];
int p[N], eid;
void init() {
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v, int c) {
e[eid].v = v;
e[eid].c = c;
e[eid].nxt = p[u];
p[u] = eid ++;
}
int dfn[N], tot, fa[N][21], dep[N];
ll Dep[N];
void dfs(int u) {
dfn[u] = ++ tot;
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v, c = e[i].c;
if(v == fa[u][0]) continue;
fa[v][0] = u, dep[v] = dep[u] + 1;
Dep[v] = Dep[u] + c;
dfs(v);
}
}
int LCA(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
for(int i = 19; i >= 0; i --) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
if(x == y) return x;
for(int i = 19; i >= 0; i --) if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
ll dis(int x, int y) {
return Dep[x] + Dep[y] - 2 * Dep[LCA(x, y)];
}
set<pii > S;
ll ans = 0;
void del(int x) {
pii o = make_pair(dfn[x], x);
auto it = S.lower_bound(o);
auto ls = it; ls = ls == S.begin() ? -- S.end() : -- ls;
auto rs = it; rs = rs == -- S.end() ? S.begin() : ++ rs;
int a = (*ls).se, b = (*rs).se;
// printf("%d %d %d %lld %lld %lld %d\n", a, b, x, dis(a, x), dis(b, x), dis(a, b), it == S.end());
ans -= dis(a, x) + dis(x, b) - dis(a, b);
S.erase(it);
}
void add(int x) {
pii o = make_pair(dfn[x], x);
if(!S.size()) {S.insert(o); return ;}
auto it = S.lower_bound(o);
auto ls = it; ls = ls == S.begin() ? -- S.end() : -- ls;
auto rs = it; rs = rs == S.end() ? S.begin() : rs;
int a = (*ls).se, b = (*rs).se;
// printf("%d %d %d %lld %lld %lld\n", a, b, x, dis(a, x), dis(b, x), dis(a, b));
ans += dis(a, x) + dis(x, b) - dis(a, b);
S.insert(o);
}
int n, m;
int main() {
init();
scanf("%d", &n);
for(int i = 1; i < n; i ++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
insert(u, v, c), insert(v, u, c);
}
dfs(1);
for(int j = 1; j <= 19; j ++)
for(int i = 1; i <= n; i ++)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
// for(int i = 1; i <= n; i ++) printf("%d ", fa[i][1]); printf("\n");
// for(int i = 1; i <= n; i ++) printf("%lld ", dep[i]); printf(" %d\n", LCA(5, 9));
scanf("%d", &m);
while(m --) {
char c;
int x;
scanf(" %c", &c);
if(c == '?') printf("%lld\n", ans / 2);
else if(c == '-') {
scanf("%d", &x);
del(x);
} else {
scanf("%d", &x);
add(x);
}
}
return 0;
}
/*
10
7 3 9
8 3 2
10 5 6
9 3 5
2 1 7
7 6 2
3 4 1
7 10 5
10 1 8
11
+ 5
+ 7
+ 2
+ 10
+ 9
+ 8
- 7
+ 3
- 10
- 2
?
*/