Atcoder Beginner Contest 231 G - Balls in Boxes(生成函数)

MARK on 2022.1.3:由于本人觉得“组合数学杂题选做”这篇博客太累赘了,故将其删除并将其中所有题解都单独开一篇博客写入。

首先列出式子:

\[ans=k![x^k]\prod\limits_{i=1}^n(\sum\limits_{j}(a_i+j)·\dfrac{1}{j!}·x^j) \]

考虑把括号里的东西拆开

\[\begin{aligned} &\sum\limits_{j}(a_i+j)·\dfrac{1}{j!}·x^j\\ =&\sum\limits_{j}a_i·\dfrac{x^j}{j!}+\sum\limits_{j}\dfrac{x^j}{(j-1)!}\\ =&\ (a_i+x)·e^x \end{aligned} \]

于是问题等价于求

\[k![x^k]e^{nx}\prod\limits_{i=1}^n(a_i+x) \]

设 \(B(x)=\prod\limits_{i=1}^n(a_i+x)\),那么

\[\begin{aligned} ans&=k!·\sum\limits_{i=0}^n[x^i]B(x)·[x^{k-i}]e^{nx}\\ &=\sum\limits_{i=0}^n[x^i]B(x)·\dfrac{n^{k-i}}{(k-i)!}·k!\\ &=\sum\limits_{i=0}^n[x^i]B(x)·n^{k-i}·k^{\underline{i}} \end{aligned} \]

分治 FFT 或者直接背包算出 \(B(x)\) 即可。时间复杂度 \(n^2\)。

int n, k, a[MAXN + 5], dp[MAXN + 5];
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	dp[0] = 1; int res = 0;
	for (int i = 1; i <= n; i++) for (int j = i; ~j; j--)
		dp[j] = (dp[j - 1] + 1ll * a[i] * dp[j]) % MOD;
	for (int i = 0; i <= min(n, k); i++) {
		int coef = 1ll * dp[i] * qpow(n, k - i) % MOD;
		for (int j = k; j > k - i; j--) coef = 1ll * coef * j % MOD;
//		printf("%d %d\n", i, coef);
		res = (res + coef) % MOD;
	}
	printf("%d\n", 1ll * res * qpow(qpow(n, MOD - 2), k) % MOD);
	return 0;
}
上一篇:简单使用grunt、bower工具合并压缩js和css


下一篇:IOS内存管理「1」- 引用计数