[bzoj3157][bzoj3516][数论]国王奇遇记/国王奇遇记加强版

63 篇文章 0 订阅

Description


∑ i = 1 n i m m i \sum_{i=1}^{n}i^mm^i i=1nimmi

Input

共一行包括两个正整数N和M。

Output

共一行为所求表达式的值对10^9+7取模的值。

Sample Input

5 3

Sample Output

36363

HINT

1<=N<=10^9,1<=M<=1000

题解

好高妙啊
我这种一看就只会拆斯特林数的sb没活路了啊
我们发现 m m m很小,又是一个 m 2 m^2 m2可过的玩意我就想到拆斯特林数了听说可以猜想递推
递推当然递推 m m m啦,根据题解我们递推在次幂的那个玩意
对于 f [ 0 ] f[0] f[0],他是个等比数列,直接做就好了
然后我们开始拓展
f [ k ] ∗ m = ∑ i = 1 n i k ∗ m i + 1 f[k]*m=\sum_{i=1}^n i^k*m^{i+1} f[k]m=i=1nikmi+1
类似等比数列的,我们减去自己尝试开始化简
f [ k ] ∗ ( m − 1 ) = ∑ i = 1 n i k ∗ m i + 1 − ∑ i = 1 n i k − m i f[k]*(m-1)=\sum_{i=1}^n i^k*m^{i+1}-\sum_{i=1}^n i^k-m^i f[k](m1)=i=1nikmi+1i=1nikmi
= ∑ i = 2 n + 1 ( i − 1 ) k ∗ m i − ∑ i = 1 n i k ∗ m i =\sum_{i=2}^{n+1}(i-1)^k*m^i-\sum_{i=1}^n i^k*m^i =i=2n+1(i1)kmii=1nikmi
= n k ∗ m n + 1 + ∑ i = 1 n m i ∗ [ ( i − 1 ) k − i k ] =n^k*m^{n+1}+\sum_{i=1}^{n}m^i*[(i-1)^k-i^k] =nkmn+1+i=1nmi[(i1)kik]
后面二项式展开得到
= n k ∗ m n + 1 + ∑ i = 1 n m i ∗ ( ∑ j = 0 k i j ∗ ( − 1 ) k − j ∗ C k j − i k ) =n^k*m^{n+1}+\sum_{i=1}^{n}m^i*(\sum_{j=0}^{k}i^j*(-1)^{k-j}*C_k^j-i^k) =nkmn+1+i=1nmi(j=0kij(1)kjCkjik)
= n k ∗ m n + 1 + ∑ i = 1 n m i ∗ ∑ j = 0 k − 1 i j ∗ ( − 1 ) k − j ∗ C k j =n^k*m^{n+1}+\sum_{i=1}^{n}m^i*\sum_{j=0}^{k-1}i^j*(-1)^{k-j}*C_k^j =nkmn+1+i=1nmij=0k1ij(1)kjCkj
套路地交换求和次序
= n k ∗ m n + 1 + ∑ j = 0 k − 1 ( − 1 ) k − j ∗ C k j ∗ ∑ i = 1 n m i ∗ i j =n^k*m^{n+1}+\sum_{j=0}^{k-1}(-1)^{k-j}*C_k^j*\sum_{i=1}^{n}m^i*i^j =nkmn+1+j=0k1(1)kjCkji=1nmiij
注意到后面是我们 f f f的定义式
所以递推有
f [ k ] = n k ∗ m n + 1 + ∑ j = 0 k − 1 ( − 1 ) k − j ∗ C k j ∗ f [ j ] m − 1 f[k]=\frac{n^k*m^{n+1}+\sum_{j=0}^{k-1}(-1)^{k-j}*C_k^j*f[j]}{m-1} f[k]=m1nkmn+1+j=0k1(1)kjCkjf[j]
优美的 m 2 m^2 m2
有时候
推推递推式会使得题目更加优美…
似乎还有 O ( m ) O(m) O(m)的神仙做法?咕了咕了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int stack[20];
inline void write(int x)
{
	if(x<0){putchar('-');x=-x;}
    if(!x){putchar('0');return;}
    int top=0;
    while(x)stack[++top]=x%10,x/=10;
    while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXM=1005;
const int mod=1e9+7;
int pow_mod(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1)ret=1LL*ret*a%mod;
		a=1LL*a*a%mod;b>>=1;
	}
	return ret;
}
int n,m;
int f[MAXM];
int C[MAXM][MAXM];
void ad(int &x,int y){x+=y;if(x>=mod)x-=mod;}
void dl(int &x,int y){x-=y;if(x<0)x+=mod;}
int main()
{
	n=read();m=read();
	if(m==1)pr2(1LL*n*(n+1)/2%mod);
	else
	{
		for(int i=0;i<MAXM;i++)
		{
			C[i][0]=1;
			for(int j=1;j<MAXM;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
		}
		int inv=pow_mod(m-1,mod-2),pw=pow_mod(m,n+1);
		f[0]=1LL*m*(pow_mod(m,n)-1)%mod*inv%mod;
		for(int i=1;i<=m;i++)
		{
			pw=1LL*pw*n%mod;
			f[i]=pw;
			for(int j=0;j<i;j++)
			{
				if((i-j)&1)dl(f[i],1LL*C[i][j]*f[j]%mod);
				else ad(f[i],1LL*C[i][j]*f[j]%mod);
			}
			f[i]=1LL*f[i]*inv%mod;
		}
		pr2(f[m]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值