传送门
传送门
随便推一波式子然后O(m^2)dp即可。
令
f
(
i
)
=
∑
k
=
1
n
k
i
m
k
f(i)=\sum_{k=1}^nk^im^k
f(i)=∑k=1nkimk
然后用扰乱法化简:
(
m
−
1
)
f
(
i
)
=
∑
k
=
1
n
k
i
m
k
+
1
−
∑
k
=
1
n
k
i
m
k
(m-1)f(i)=\sum_{k=1}^nk^im^{k+1}-\sum_{k=1}^nk^im^k
(m−1)f(i)=∑k=1nkimk+1−∑k=1nkimk
最后化简出来可以
O
(
m
2
)
O(m^2)
O(m2)递推
注意特判
m
=
1
m=1
m=1的情况。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int mod=1e9+7;
typedef long long ll;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=1005;
int n,m,f[N],inv[N],fac[N],ifac[N],d;
inline void init(){
inv[1]=ifac[0]=ifac[1]=fac[0]=fac[1]=1;
for(ri i=2;i<=m;++i)fac[i]=mul(fac[i-1],i);
for(ri i=2;i<=m;++i)inv[i]=mul(inv[mod-mod/i*i],mod-mod/i),ifac[i]=mul(ifac[i-1],inv[i]);
}
inline int C(int n,int m){return mul(fac[n],mul(ifac[m],ifac[n-m]));}
int main(){
cin>>n>>m;
if(m==1)return cout<<(ll)n*(n+1)/2%mod,0;
init();
f[0]=mul(dec(d=ksm(m,n+1),m),inv[m-1]);
for(ri t,w=n,i=1;i<=m;++i,Mul(w,n)){
f[i]=mul(w,d);
for(ri j=0,ff=i&1;j<i;++j,ff^=1)t=mul(f[j],C(i,j)),ff?Dec(f[i],t):Add(f[i],t);
Mul(f[i],inv[m-1]);
}
cout<<f[m];
return 0;
}