BZOJ 3157: 国王奇遇记 (数学)

题面:BZOJ3157

一句话题意:

求:

\[\sum_{i=1}^ni^m\ \times m^i\ (mod\ 1e9+7)\ \ (n \leq 1e9,m\leq200) \]

题解

\[DP[i]=\sum_{k=1}^n k^i*m^k \]

\[(m-1)DP[i]=mDP[i]-DP[i] \]

\[=\sum_{k=1}^{n}k^im^{k+1}-\sum_{k=1}^nk^im^k \]

\[=\sum_{k=2}^{n+1}(k-1)^im^k-\sum_{k=1}^nk^im^k \]

\[=n^n m^{n+1}+\sum_{k=1}^nm^k*((k-1)^i-k^i) \]

由二项式反演得

\[=n^im^{n+1}+\sum_{k=1}^n \sum_{j=1}^{i-1}(-1)^{i-j}*C_i^j\ k^jm^k \]

\[=n^im^{n+1}+\sum_{j=0}^{i-1}(-1)^{i-j}*C_i^j\times DP[j] \]

于是就可以\(O(m^2log(mod))\)递推了!

#include<bits/stdc++.h>

using namespace std;

namespace Tzh{
	
	typedef long long ll;
	const int maxm=210;
	const ll p=1e9+7;
	ll n,m,dp[maxm],c[maxm][maxm];
	
	ll qpow(ll a,ll b){
		ll sum=1;
		while(b){
			if(b&1) sum=sum*a%p;
			a=a*a%p; b>>=1;	
		}
		return sum;
	}
	
	void init(){c[0][0]=1;
		for(int i=1;i<=m;i++){c[i][0]=1;
			for(int j=1;j<=i;j++)
				c[i][j]=(c[i-1][j]+c[i-1][j-1])%p;	
		}
	}
	
	void work(){
		scanf("%lld%lld",&n,&m); init();
		if(m==1){
			printf("%lld",(n+1)*n/2%p);
			return ;	
		}
		dp[0]=(qpow(m,n+1)-m+p)%p*qpow(m-1,p-2)%p;
		for(int i=1;i<=m;i++){
			dp[i]=qpow(n,i)*qpow(m,n+1)%p;
			for(int j=0;j<i;j++)
				dp[i]=(dp[i]+p+((i-j)&1?-1:1)*c[i][j]*dp[j]%p)%p;
			dp[i]=dp[i]*qpow(m-1,p-2)%p;
		}
		printf("%lld",dp[m]);
		return ;	
	}
}

int main(){
	Tzh::work();
	return 0;	
}
posted @ 2018-06-14 15:11  Jack_the_Ripper  阅读(177)  评论(0编辑  收藏  举报