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
*/

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/10198062.html