题解:P16905 [CCO 2026] Tree Traversals
分析
首先
对于
这样
定义状态函数
解得
记
显然,这个儿子一定是
记
- 对于
\lceil\frac{K+2dep_u}{2}\rceil=x 的询问。应该乘上\frac{\binom{cnt_u(y)-1}{cnt_v(y)-1}}{\binom{cnt_u(y)}{cnt_{v}(y)}} 。其中v 是u 的长儿子。
这样长剖一下就能直接维护
时间复杂度
我写的
代码
const int N = 1e6 + 10, mod = 1e9 + 7;
int n, q;
vector<int> e[N];
int dep[N], mdep[N], id[N], L[N], R[N];
vector<int> cnt[N];
int fac[N], inv[N];
int Cnt[N], dt[N];
int Kmin;
il int C(int n, int m){
if(n < m || m < 0) return 0;
return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
il void init(){
fac[0] = 1;
UU(i, 1, N) fac[i] = fac[i - 1] * i % mod;
UU(i, 0, N) inv[i] = qmi(fac[i], mod - 2, mod);
return ;
}
il void dfs0(int u, int fa){
dep[u] = dep[fa] + 1;
++ Cnt[dep[u]];
mdep[u] = dep[u], id[u] = u;
for(auto v: e[u]) if(v != fa){
dfs0(v, u);
if(mdep[v] > mdep[u]) mdep[u] = mdep[v], id[u] = id[v];
}
R[id[u]] = max(R[id[u]], dep[u]);
L[id[u]] = dep[u];
return ;
}
il void dfs1(int u, int fa){
int mdep_ = -1;
for(auto v: e[u]) if(v != fa){
dfs1(v, u);
if(id[v] != id[u]) mdep_ = max(mdep_, mdep[v]);
}
if(~mdep_) Kmin = max(Kmin, 2 * mdep_ - 2 * dep[u]);
int cnt_ = (mdep_ != -1 ? cnt[id[u]][mdep_ - L[id[u]] + 1] : 0);
for(auto v: e[u]) if(v != fa && id[v] != id[u]){
U(x, 1, R[id[v]] - L[id[v]] + 1){
int Dep = L[id[v]] + x - 1 - L[id[u]] + 1;
cnt[id[u]][Dep] += cnt[id[v]][x];
}
}
++ cnt[id[u]][dep[u] - L[id[u]] + 1];
if(mdep_ + 1 <= mdep[u] && (~mdep_)){
// assert(mdep_ + 1 <= mdep[u]);
int k_ = 2 * mdep_ - 2 * dep[u];
int Delta = C(cnt[id[u]][mdep_ - L[id[u]] + 1] - 1, cnt_ - 1) * qmi(C(cnt[id[u]][mdep_ - L[id[u]] + 1], cnt_), mod - 2, mod) % mod;
U(k, k_ - 1, k_ + 1) if(k >= 0){
if((k + 2 * dep[u] - 1) / 2 + 1 == mdep_){
dt[k] = dt[k] * Delta % mod;
}
}
}
return ;
}
il void solve(){
n = rd, q = rd;
{
Kmin = 0;
U(i, 0, n + 1){
L[i] = R[i] = 0;
vector<int> ().swap(e[i]);
vector<int> ().swap(cnt[i]);
Cnt[i] = 0;
dt[i] = 1;
}
}
UU(i, 1, n){
int u = rd, v = rd;
e[u].emplace_back(v),
e[v].emplace_back(u);
}
dfs0(1, 0);
U(i, 1, n) if(id[i] == i){
cnt[i].resize(R[i] - L[i] + 2);
U(x, 1, R[i] - L[i] + 1) cnt[i][x] = 0;
}
int F = 1;
U(i, 1, mdep[1]) F = F * fac[Cnt[i]] % mod;
dfs1(1, 0);
while(q --){
int K = rd;
if(K < Kmin) cout << "0 ";
else cout << F * dt[K] % mod << " ";
}
puts("");
return ;
}