Luogu6620 组合数问题 - 第二类斯特林数 -

题目链接:https://www.luogu.com.cn/problem/P6620

题解:
其实就一个式子
image

证明可以利用这个式子找一下规律 k(nk)=n(n1k1)

回到原题,把多项式拆开之后的形式就是开头式子左边的部分,利用得到的式子可以直接O(m2logm)的计算

事实上,一个幂可以转化成下降幂的和,系数多一个第二类斯特林数
image
另外,原式的证明也可以利用求导

(1+x)n=k=0n(nk)xk

如果左右都取二阶导,则有

ni_(1+x)ni=k=0n(nk)ki_xki

同乘一个 i 即可

// by SkyRainWind
#include <bits/stdc++.h>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>

using namespace std;

typedef long long ll;
typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f;

int n,x,mod,m;
int S[1005][1005];

int pw(int x,int y){
	if(!y)return 1;
	if(y==1)return x;
	int mid=pw(x,y>>1);
	if(y&1)return 1ll*mid*mid%mod*x%mod;
	return 1ll*mid*mid%mod;
}
int C[1005][1005],a[1005];

signed main(){
	scanf("%d%d%d%d",&n,&x,&mod,&m);
	for(int i=0;i<=m;i++)scanf("%d",&a[i]);
	S[1][1] = 1;
	for(int i=2;i<=1000;i++)
		for(int j=1;j<=1000;j++)
			(S[i][j] = S[i-1][j-1]+1ll*j*S[i-1][j]%mod) %= mod;
	C[0][0] = 1;
	for(int i=1;i<=1000;i++){
		C[i][0] = 1;
		for(int j=1;j<=i;j++)C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
	}
	
	ll ans = 1ll * a[0] * pw(x+1, n) % mod;
	for(int p=1;p<=m;p++){
		int cans = 0, ndown = n;
		for(int i=1;i<=p;i++){
			(cans += 1ll * ndown * S[p][i] % mod * pw(x,i) % mod * pw(1+x,n-i) % mod) %= mod;
			ndown = 1ll*ndown * (n-i) % mod;
		}
		(ans += 1ll*cans*a[p]%mod) %= mod;
	}
	cout<<ans;

	return 0;
}
posted @   SkyRainWind  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示