【题解】CF1667E-Centroid Probabilities

求对于所有大小为 n 的树,满足每个结点 2in 向小于 i 的点连恰好一条边,对于每个点 x 求出有多少颗树以 x 为重心。

有一个非常妙的转化,我们求出 fi 表示以 i 为根的子树大小 n+12 的方案,那么 i 为重心的方案就是 fi 种方案中子树中所有点子树大小 <n+12 的方案。

也就是如果我们求出了 f,那么就可以容斥出 ans,其中

ansi=fi1ij>iansj

这个式子意义是用 fi,减去重心出现在子树里的方案,每一个出现在子树里的方案,我们记重心为 x,它第一个 i 的祖先是 y,那么所有 y[1,i] 的方案是相同的。

那么怎么求出 fi,直接枚举 j 表示 i 的子树大小,式子就是若干个阶乘,算一算即可。我们令 m=n+12

fi=jm(nij1)(nj1)!(i1)!(j1)!=(ni)!(nm)!(nmi+1)!

这样就可以 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;
}

作者:7KByte

出处:https://www.cnblogs.com/7KByte/p/16249309.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   7KByte  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示