luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数)

luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数)

Luogu

题外话:

LN切这题的人比切T1的多。

我都想到了组合意义乱搞也想到可能用斯特林数为啥还是没做出来。。。

我怕不是除了数据结构啥也不会。

我是傻逼。

题解时间

不弄纯柿子推导,来点阳间的组合意义证明。

首先毫无疑问拆成: $$ \sum_{i=0}^{m} a_{i} \sum_{k=0}^{n} k^{i} \cdot x^{k} \cdot \binom{n}{k} $$

然后考虑如何求 $$ \sum_{k=0}^{n} k^{i} \cdot x^{k} \cdot \binom{n}{k} $$

从组合意义考虑: $ n $ 个不同盒子 $ i $ 个不同的球,盒子可以染 $ n $ 种颜色之一或者不染色,之后将所有球装进染色的盒子里。

转换成:选择在 $ j $ 个盒子里放所有的球,之后这 $ j $ 个盒子必须染色,其余可染可不染,而放球的方案数是 $ \begin{Bmatrix}i \newline j\end{Bmatrix} j! $

就变成了 $$ \sum_{j=0}^{i} \binom{n}{j} x^{j} (x+1)^{n-j} \begin{Bmatrix}i \newline j\end{Bmatrix} j! $$

#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
// #define int long long
struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
template<typename TP>inline void read(TP &tar)
{
	TP ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
	tar=ret*f;
}
template<typename TP,typename... Args>inline void read(TP& t,Args&... args){read(t),read(args...);}
namespace RKK
{
const int N=1011;
int n,m,x,mo,a[N],s[N][N];
int fpow(int a,int p){int ret=1;while(p){if(p&1)ret=(lint)ret*a%mo;a=(lint)a*a%mo,p>>=1;}return ret;}

signed main()
{
	read(n,x,mo,m);for(int i=0;i<=m;i++) read(a[i]);
	s[0][0]=1;for(int i=1;i<=1000;i++)for(int j=1;j<=i;j++) s[i][j]=(s[i-1][j-1]+1ll*s[i-1][j]*j)%mo;
	int ans=0;
	for(int i=0;i<=m;i++)
	{
		int fc=1,tmp=0;
		for(int j=0;j<=i;j++)
			tmp=(tmp+1ll*fc*s[i][j]%mo*fpow(x,j)%mo*fpow(x+1,n-j))%mo,fc=1ll*fc*(n-j)%mo;
		ans=(ans+1ll*a[i]*tmp)%mo;
	}printf("%d\n",ans);
	return 0;
}
}
signed main(){return RKK::main();}

猜你喜欢

转载自www.cnblogs.com/rikurika/p/13204518.html