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

首先常规地把\(f(k)\)拆开:

\[\sum_{k=0}^nf(k)x^k\binom{n}{k}=\sum_{i=0}^ma_i\sum_{k=0}^nk^ix^k\binom{n}{k} \]

然后证明一个组合恒等式:

\[\sum_{k=0}^nk^ix^k\binom{n}{k}=\sum_{j=0}^in^{\underline{j}}x^j(1+x)^{n-j}\begin{Bmatrix}i\\j\end{Bmatrix} \]

\(\square\) 考虑它的组合意义:有\(n\)个不同的盒子,每个盒子可以染成\(x\)种不同的颜色,也可以不染。将\(i\)个不同的球放入这些盒子中有颜色的盒子里,不同的方案个数。

考虑从两个方面计数:

  • 先枚举有\(k\)个盒子被染色(\(\binom{n}{k}\)),每个盒子有\(x\)种选择(\(x^k\)),每个球只能放进这\(k\)个有色的盒子里(\(k^i\)),于是总共为:

\[\sum_{k=0}^n\binom{n}{k}x^kk^i=LHS \]

  • 先枚举有\(j\)个盒子放了球(\(\binom{n}{j}\)),那么这些盒子一定要被染成\(x\)种颜色之一(\(x^j\)),剩下\(n-j\)个不放球盒子可染可不染(\((1+x)^{n-j}\)),最后别忘了乘上将\(i\)个球放入这些盒子的方案数(\(S(i,j)j!\),乘上\(j!\)是因为第二类斯特林数只考虑了盒子之间无序的情况),总共为:

\[\sum_{j=0}^i\binom{n}{j}x^j(i+x)^{n-j}\begin{Bmatrix}i\\j\end{Bmatrix}j=\sum_{j=0}^in^{\underline{j}}x^j(1+x)^{n-j}\begin{Bmatrix}i\\j\end{Bmatrix}=RHS \]

因为这两种是对同一个组合问题的计数,于是\(LHS=RHS\)。\(\blacksquare\)

那么原式就变成了:

\[\sum_{k=0}^nf(k)x^k\binom{n}{k}=\sum_{i=0}^ma_i\sum_{j=0}^in^{\underline{j}}x^j(1+x)^{n-j}\begin{Bmatrix}i\\j\end{Bmatrix} \]

把该预处理的预处理一下就能做到\(O(m^2)\)了。

代码:

#include<cstdio>
#define N 1005

int n,x,P,m,a[N];

int s[N][N];

inline int fpow(int y,int k){
	int res=1;
	for(;k;k>>=1,y=1ll*y*y%P)
		if(k&1)
			res=1ll*res*y%P;
	return res;
}

int tmp[N]; 

int ans;

int main(){
	scanf("%d%d%d%d",&n,&x,&P,&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]=(s[i-1][j-1]+1ll*j*s[i-1][j]%P)%P;
	for(int i=0;i<=m;i++){
		tmp[i]=fpow(x+1,n-i);
		for(int j=i-1;j>=0;j--)
			tmp[j]=1ll*tmp[j+1]*(x+1)%P;
		for(int j=0,t1=1,t2=1;j<=i;j++,t1=1ll*t1*(n-j+1)%P,t2=1ll*t2*x%P)
			ans=(ans+1ll*a[i]*s[i][j]%P*t1%P*t2%P*tmp[j]%P)%P;
	}
	printf("%d",ans);
	
    #define w 0
    return ~~('0')?(0^w^0):(0*w*0);
}
上一篇:bzoj4671 异或图(斯特林反演,线性基)


下一篇:opengl算法学习---图形几何变换