bzoj 3157 国王奇遇记 - 数学

……没有任何算法的推式子……

Fk=i=1nik×mi

Fk=i=1n(i1+1)k×mi1+1

Fk=m+i=1n1(i+1)k×mi+1

Fk=m(n+1)k×mn+1+i=1n(i+1)k×mi+1

Fk=m(n+1)k×mn+1+i=1nj=0k(kj)ij×mi+1

Fk=m(n+1)k×mn+1+mj=0k(kj)i=1nij×mi

Fk=m(n+1)k×mn+1+mj=0k(kj)Fj

(m1)Fk=(n+1)k×mn+1mmj=0k1(kj)Fj

Fk=(n+1)k×mn+1mmj=0k1(kj)Fjm1

特判m=1的情况,其余这样转移即可,平方复杂度。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 210
#define lint long long
#define mod 1000000007
#define inv(x) fast_pow(x,mod-2)
using namespace std;
int s[N],c[N][N],mi[N];
inline int fast_pow(int x,int k,int ans=1)
{
    for(;k;k>>=1,x=(lint)x*x%mod)
        if(k&1) ans=(lint)ans*x%mod;
    return ans;
}
int main()
{
    int n,m,t;scanf("%d%d",&n,&m),mi[0]=fast_pow(m,n+1),t=inv(m-1);
    if(m==1) return !printf("%lld\n",(lint)n*(n+1)%mod*inv(2)%mod);
    for(int i=1;i<=m;i++) mi[i]=(lint)mi[i-1]*(n+1)%mod;
    s[0]=(lint)t*(mi[0]-m+mod)%mod,c[0][0]=1;
    for(int i=1;i<=m;i++)
        for(int j=c[i][0]=1;j<=i;j++)
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    for(int i=1;i<=m;i++)
    {
        for(int j=(s[i]=1)-1;j<i;j++)
            (s[i]+=(lint)c[i][j]*s[j]%mod)%=mod;
        s[i]=(lint)t*(mi[i]-(lint)m*s[i]%mod+mod)%mod;
    }
    return !printf("%d\n",s[m]);
}
阅读更多

没有更多推荐了,返回首页