2021.3.22
\(\mathcal{A}\)
[HNOI2014]世界树
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
namespace cxcyl {
const int N = 300300, inf = (int)1e9;
int n, m, rt, tp, a[N], bo[N], dfn[N], siz[N], dep[N], tn[N], up[N];
int f[N][21], s[N], ans[N], A[N], timer;
pair<int, int> g[N];
vector<int> G[N], E[N];
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c > -1 && c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
if (c == -1) return 0;
while (c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
void dfs0(int u) {
for (int i = 1; i <= 20; ++i)
f[u][i] = f[f[u][i - 1]][i - 1];
dfn[u] = ++timer;
siz[u] = 1;
for (int v : G[u])
if (!dfn[v]) {
f[v][0] = u;
dep[v] = dep[u] + 1;
dfs0(v);
siz[u] += siz[v];
}
}
void dfs1(int u) {
g[u] = make_pair(bo[u] ? 0 : inf, u);
for (int v : E[u]) {
dfs1(v);
g[u] = min(g[u], make_pair(g[v].fi + dep[v] - dep[u], g[v].se));
}
}
void dfs2(int u, int D, int x) {
if (make_pair(D, x) < g[u])
g[u] = make_pair(D, x);
else {
D = g[u].fi;
x = g[u].se;
}
for (int v : E[u])
dfs2(v, D + dep[v] - dep[u], x);
}
void dfs3(int u) {
tn[u] = g[u].se;
ans[tn[u]] += siz[u];
for (int v : E[u]) {
int x = v;
for (int i = 20; i >= 0; --i)
if (dep[f[x][i]] > dep[u])
x = f[x][i];
ans[tn[u]] -= siz[up[v] = x];
dfs3(v);
}
}
void dfs4(int u) {
for (int v : E[u]) {
int x = up[v], y = v, H;
if (tn[u] == tn[v])
ans[tn[u]] += siz[x] - siz[v];
else {
H = dep[tn[v]] + dep[u] - g[u].first;
H = H & 1 ? H + 1 >> 1 : (tn[v] < tn[u] ? H >> 1 : (H >> 1) + 1);
for (int i = 20; i >= 0; --i)
if (dep[f[y][i]] >= H)
y = f[y][i];
ans[tn[v]] += siz[y] - siz[v];
ans[tn[u]] += siz[x] - siz[y];
}
dfs4(v);
}
}
void dfs5(int u) {
up[u] = tn[u] = 0;
for (int v : E[u]) dfs5(v);
E[u].clear();
}
inline int lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int len = dep[u] - dep[v];
for (int i = 0; i <= 20; ++i) if (len >> i & 1) u = f[u][i];
for (int i = 20; i >= 0; --i) if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
return u == v ? u : f[u][0];
}
inline int main() {
n = read();
for (int i = 1; i < n; ++i) {
int u = read(), v = read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs0(1);
for (int T = read(); T--; ) {
//clear
int m = read();
for (int i = 1; i <= m; ++i) {
A[i] = a[i] = read();
bo[a[i]] = 1;
}
sort(a + 1, a + m + 1, [](int x, int y) { return dfn[x] < dfn[y]; });
s[tp = 1] = a[1];
for (int i = 2; i <= m; ++i) {
int l = lca(a[i], s[tp]);
while (tp > 1 && dep[l] <= dep[s[tp - 1]]) {
E[s[tp - 1]].push_back(s[tp]);
--tp;
}
if (s[tp] != l) {
E[l].push_back(s[tp]);
s[tp] = l;
}
s[++tp] = a[i];
}
while (tp > 1) {
E[s[tp - 1]].push_back(s[tp]);
--tp;
}
rt = s[1];
dfs1(rt);
dfs2(rt, g[rt].fi, g[rt].se);
dfs3(rt);
dfs4(rt);
ans[tn[rt]] += siz[1] - siz[rt];
for (int i = 1; i <= m; ++i)
printf("%d ", ans[A[i]]);
puts("");
//clear
dfs5(rt);
for (int i = 1; i <= m; ++i)
bo[a[i]] = ans[a[i]] = 0;
}
return 0;
}
} int main() { return cxcyl::main(); }