Description
求
∑ i = 1 n i m m i \sum_{i=1}^{n}i^mm^i i=1∑nimmi
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=1∑nik∗mi+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]∗(m−1)=i=1∑nik∗mi+1−i=1∑nik−mi
= ∑ 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=2∑n+1(i−1)k∗mi−i=1∑nik∗mi
= 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] =nk∗mn+1+i=1∑nmi∗[(i−1)k−ik]
后面二项式展开得到
= 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) =nk∗mn+1+i=1∑nmi∗(j=0∑kij∗(−1)k−j∗Ckj−ik)
= 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 =nk∗mn+1+i=1∑nmi∗j=0∑k−1ij∗(−1)k−j∗Ckj
套路地交换求和次序
= 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 =nk∗mn+1+j=0∑k−1(−1)k−j∗Ckj∗i=1∑nmi∗ij
注意到后面是我们 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]=m−1nk∗mn+1+∑j=0k−1(−1)k−j∗Ckj∗f[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;
}