Loading

【题解】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;
}
posted @ 2022-05-09 15:09  7KByte  阅读(34)  评论(0编辑  收藏  举报