Description
Input
共一行包括两个正整数N和M。
Output
共一行为所求表达式的值对10^9+7取模的值。
特判m=1
m≠1时:
设S[u]=sigma(i^u*m^i)
m*S[u]=sigma(i^u*m^(i+1))
=sigma((i-1)^u*m^i)+n^u*m^(n+1)
两式相减得(m-1)*S[u]=n^u*m^(n+1)-sigma((i^u-(i-1)^u)*m^i)
S[u]=(n^u*m^(n+1)-sigma((i^u-(i-1)^u)*m^i))/(m-1)
i^u-(i-1)^u可以展开,从而由S[0..u-1]计算出S[u],预处理二项式系数(组合数)即可
边界条件S[0]=sigma(m^i)=(m^n-1)*m/(m-1)
除法要取逆元
时间复杂度为O(m2logn)
#include<cstdio> typedef long long lint; const int P=1000000007; lint f[1024][1024]; lint s[1024]; bool d[1024]; int n,m; lint power(lint x,lint t){ lint v=1,c=x; while(t){ if(t&1)v=v*c%P; c=c*c%P; t>>=1; } return v; } lint div(lint a,lint b){ return a*power(b,P-2)%P; } lint S(int m1){ if(d[m1])return s[m1]; lint v=power(n,m1)*power(m,n+1)%P; for(int i=m1-1,j=-1;i>=0;i--,j=-j){ lint r=S(i)*f[m1+1][i+1]*j; v+=r; v%=P; } v=div(v,m-1); d[m1]=1; return s[m1]=v; } int main(){ scanf("%d%d",&n,&m); if(m==1){ printf("%lld",n*1ll*(n+1)/2%P); return 0; } f[1][1]=1; d[0]=1; s[0]=div(power(m,n)-1,m-1)*m%P; for(int i=2;i<=m+1;i++){ for(int j=1;j<=i;j++)f[i][j]=(f[i-1][j]+f[i-1][j-1])%P; } printf("%lld ",(S(m)+P)%P); return 0; }