bzoj3157: 国王奇遇记
emmm。。。。。。
直接看题解好了:
BZOJ-3157. 国王奇遇记 – Miskcoo's Space
O(m)不懂扔掉
总之,给我们另一个处理复杂求和的方法:
找到函数之间的递推公式!
这里用错位相减,然后想办法转化
由于根据二项式定理,展开之后会出现k^i的乘方,所以展开,有助于变成f(j)递推下去
O(m^2)
#include<bits/stdc++.h> #define reg register int #define il inline #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=1005; const int mod=1e9+7; ll C[N][N]; int n,m; ll f[N]; ll qm(ll x,ll y){ ll ret=1; while(y){ if(y&1) ret=ret*x%mod; x=x*x%mod; y>>=1; } return ret; } int main(){ rd(n);rd(m); if(m==1){ ll ans=((ll)n*(n+1))%mod*qm(2,mod-2)%mod; printf("%lld",ans); return 0; } C[0][0]=1; for(reg i=1;i<=m;++i){ C[i][0]=1; for(reg j=1;j<=m;++j){ C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; } } f[0]=m*(qm(m,n)-1+mod)%mod*qm(m-1,mod-2)%mod; for(reg i=1;i<=m;++i){ for(reg j=0;j<=i-1;++j){ if((i-j)&1){ f[i]=(f[i]-C[i][j]*f[j]%mod+mod)%mod; }else{ f[i]=(f[i]+C[i][j]*f[j]%mod)%mod; } } f[i]=(f[i]+qm(n,i)*qm(m,n+1)%mod)%mod; f[i]=(f[i]*qm(m-1,mod-2))%mod; } printf("%lld",f[m]); return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2018/12/29 16:48:22 */