CodeForces 622F

http://codeforces.com/problemset/problem/622/F

拉格朗日插值

#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;

typedef __int64 LL;
LL p[N];
LL _pow(LL a,int b){
    LL c=1;
    while(b){
        if(b&1){
            c*=a;c%=mod;
        }
        a*=a;a%=mod;b/=2;
    }
    return c;
}

LL jie[N],inv[N];
void init(){
    int n=1e6+2;
    jie[0]=inv[0]=1;
    for(int i=1;i<=n;i++){
        jie[i]=jie[i-1]*i%mod;
    }
    for(int i=n;i>=1;i--){
        if(i==n){
            inv[i]=_pow(jie[i],mod-2);
        }
        else {
            inv[i]=inv[i+1]*(i+1)%mod;
        }
    }
}

LL gao(int n,int k,int id){
    LL bns=inv[id-1]*inv[k+2-id]%mod;
    if((id-(k+2))%2)bns=-bns;
    bns=(bns+mod)%mod;
    return bns;
}

LL fun(int n,int k){
    LL ans=0;
    LL tmp=1;
    for(int i=1;i<=k+2;i++){
        tmp=tmp*(n-i)%mod;
    }
    for(int i=1;i<=k+2;i++){
        ans+=p[i]*gao(n,k,i)%mod*tmp%mod*_pow(n-i,mod-2)%mod;
        ans%=mod;
    }
    return ans;
}

int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // gh546
    int n,k;
    init();
    while(scanf("%d%d",&n,&k)!=EOF){
        p[0]=0;
        for(int i=1;i<=k+2;i++){
            p[i]=p[i-1]+_pow(i,k);
            p[i]%=mod;
            //printf("%I64d ",p[i]);
        }
        if(n<=k+2){
            printf("%I64d\n",p[n]);
        }
        else {
           printf("%I64d\n",fun(n,k));
        }
    }
    return 0;
}


你可能感兴趣的:(数学)