题解:
虽然我知道这只是弱化版,不过其他两道太神了看不懂,而且今天学的扩展板也还没有消化,就先水一水这道题吧。
观察这个式子: fn,m=∑i=1nimmi f n , m = ∑ i = 1 n i m m i
n
n
远远大于,不能直接枚举。
那么怎么办?递推!
fn,m
f
n
,
m
的大部分信息在前面已经计算出来过,我们可以想办法构造递推式。 不妨记
fn,j=∑i=0nijmi(j≠0)
f
n
,
j
=
∑
i
=
0
n
i
j
m
i
(
j
≠
0
)
。考虑从
fn,k(k<j)
f
n
,
k
(
k
<
j
)
的递推:
注意第二步的转移虽然看起来很莫名其妙,其实是利用组合数构造了这一个递推式子。
O(m2)
O
(
m
2
)
做动态规划即可。
(可以利用多项式插值或者快速傅里叶变换求解
∑i=0nfimi
∑
i
=
0
n
f
i
m
i
且
fi
f
i
是
k(k≤5e5)
k
(
k
≤
5
e
5
)
次多项式的问题,以后会把这个坑填上)。
upt :已经填坑,具体请看:http://blog.csdn.net/qq_35649707/article/details/79595192
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e2+50;
const int mod=1e9+7;
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int add(int x,int y) {return (x+y>=mod)?(x+y-mod):x+y;}
inline int dec(int x,int y) {return (x-y<0)?(x-y+mod):x-y;}
inline int power(int a,int b) {
int rs=1;
for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a);
return rs;
}
int n,m,a,inv,c[N][N],s[N],pw[N],f[N];
int main() {
cin>>n>>m; pw[0]=1; a=power(m,n);
inv=power(mod+1-m,mod-2);
if(m==1) {printf("%d\n",(LL)n*(n+1)/2%mod); return 0;}
for(int i=0;i<=m;i++) c[i][0]=1;
for(int i=1;i<=m;i++) pw[i]=mul(pw[i-1],n);
for(int i=1;i<=m;i++) for(int j=1;j<=i;j++) c[i][j]=add(c[i-1][j-1],c[i-1][j]);
f[0]=mul(dec(power(m,n+1),1),power(m-1,mod-2));
for(int i=1;i<=m;i++) {
int rs=mod-mul(pw[i],a);
for(int j=0;j<i;j++) rs=add(rs,mul(c[i][j],dec(f[j],(LL)pw[j]*a%mod)));
rs=mul(rs,m); rs=mul(rs,inv); f[i]=rs;
}
printf("%d\n",f[m]);
}