【题解】CF1667E-Centroid Probabilities
求对于所有大小为 \(n\) 的树,满足每个结点 \(2\le i \le n\) 向小于 \(i\) 的点连恰好一条边,对于每个点 \(x\) 求出有多少颗树以 \(x\) 为重心。
有一个非常妙的转化,我们求出 \(f_i\) 表示以 \(i\) 为根的子树大小 \(\ge \dfrac{n+1}{2}\) 的方案,那么 \(i\) 为重心的方案就是 \(f_i\) 种方案中子树中所有点子树大小 \(< \dfrac{n + 1}{2}\) 的方案。
也就是如果我们求出了 \(f\),那么就可以容斥出 \(ans\),其中
\[ans_i = f_i - \frac{1}{i}\sum\limits_{j > i}ans_j
\]
这个式子意义是用 \(f_i\),减去重心出现在子树里的方案,每一个出现在子树里的方案,我们记重心为 \(x\),它第一个 \(\le i\) 的祖先是 \(y\),那么所有 \(y\in [1,i]\) 的方案是相同的。
那么怎么求出 \(f_i\),直接枚举 \(j\) 表示 \(i\) 的子树大小,式子就是若干个阶乘,算一算即可。我们令 \(m=\dfrac{n + 1}{2}\)
\[f_i = \sum\limits_{j \ge m}\binom{n-i}{j - 1}(n-j-1)!(i-1)!(j-1)! = \dfrac{(n-i)!(n-m)!}{(n-m-i+1)!}
\]
这样就可以 \(\mathcal{O}(N)\) 算出答案。
#define N 200005
int n, s, m, fac[N], inv[N], iv[N], ed[N];
int main() {
read(n), m = n / 2 + 1;
fac[0] = 1; rp(i, n)fac[i] = fac[i - 1] * 1LL * i % P;
inv[n] = Pow(fac[n], P - 2); pr(i, n)inv[i - 1] = inv[i] * 1LL * i % P;
iv[1] = 1; rep(i, 2, n)iv[i] = P - iv[P % i] * 1LL * (P / i) % P;
pr(i, n - m + 1){
int w = fac[n - i] * 1LL * fac[n - m] % P * inv[n - i - m + 1] % P;
su(w, iv[i] * 1LL * s % P);
ed[i] = w, ad(s, w);
}
rp(i, n)printf("%d ", ed[i]); el;
return 0;
}