[省选联考 2020 A 卷] 组合数问题

\[\begin{align} \sum_{k=0}^n\sum_{j=0}^ma_jk^j\times x^k\times \binom nk \end{align} \]

把 f(k) 转为下降幂多项式:

\[\begin{align} &\sum_{k=0}^n\sum_{j=0}^mb_jk^{\underline j}\times x^k\times \binom nk\\ &\sum_{k=0}^n\sum_{j=0}^mb_jn^{\underline j}\times x^k\times \binom{n-j}{k-j}\\ &\sum_{j=0}^mb_jn^{\underline j} \sum_{k=0}^n x^k\times \binom{n-j}{n-k}\\ &\sum_{j=0}^mb_jn^{\underline j} x^j\sum_{k=0}^{n-j} x^{n-j-k}\times \binom{n-j}{k}\\ &\sum_{j=0}^mb_jn^{\underline j} x^j(1+x)^{n-j} \end{align} \]

很妙。

#include<bits/stdc++.h>
typedef long long LL;
using namespace std;

const int M = 2e3 + 3;
int mo;

int ksm(int a, int b) {
	int res = 1;
	for(; b; b>>=1, a=((LL)a*a) % mo)
		if(b & 1) res = ((LL)res * a) % mo;
	return res;
}

int n, m, x;
int a[M], b[M], S[M][M];

int main()
{
	scanf("%d%d%d%d", &n, &x, &mo, &m);
	for(int i = 0; i <= m; ++i) scanf("%d", &a[i]);
	S[0][0] = 1;
	for(int i = 1; i <= m; ++i) {
		for(int j = 1; j <= i; ++j) {
			S[i][j] = ((LL)j * S[i-1][j] % mo + S[i-1][j-1]) % mo;
		}
	}
	for(int i = 0; i <= m; ++i) {
		for(int j = 0; j <= i; ++j) {
			b[j] += (LL)S[i][j] * a[i] % mo;
			b[j] %= mo;
		}
	}
	LL ans = 0ll;
	int n_f_j = 1;
	for(int j = 0; j <= m; ++j) {
		ans += (LL)b[j] * (LL)n_f_j % mo * (LL)ksm(x, j) % mo * (LL)ksm(x + 1, n - j) % mo;
		ans %= mo;
		n_f_j = (LL)n_f_j * (LL)(n-j) % mo;
	}
	cout << ans;
	return 0;
}
posted @ 2021-01-31 16:46  xwmwr  阅读(61)  评论(1编辑  收藏  举报