51nod 1258 序列求和

SOL:

   拉格朗日插值啊。复杂度是O(nlogn)的。

   but此题卡常数,只能套一个快速幂。还有一个要预处理掉。

 

  

#pragma GCC optimize("-O2")
#include<bits/stdc++.h>
#define LL long long
#define mo 1000000007
#define N 50007
int t;
LL n,k,ni[N],fi[N],anw[N],anp,ppp,ans,p[N],q[N];
inline LL qsm(LL x,LL y=mo-2){
    static LL anw;
    for (anw=1;y;y>>=1,x=x*x%mo) if (y&1) anw=anw*x%mo; return anw;
}
using namespace std;
signed main() {
//    freopen("aa.in","r",stdin);
//    freopen("a.out","w",stdout);
    scanf("%d",&t);
    fi[0]=1;
    for (int i=1;i<N;i++) fi[i]=fi[i-1]*i%mo; ni[N-1]=qsm(fi[N-1]);
    for (int i=N-1;i;i--) ni[i-1]=ni[i]*i%mo;
    while (t--) {
        scanf("%lld%lld",&n,&k);
        n%=mo;
        anp=1;
        for (int i=1;i<=k+2;i++) 
            anw[i]=(anw[i-1]+qsm(i,k))%mo,anp=anp*(n-i)%mo;
        if (n<=k+2) {
            printf("%lld\n",anw[n]);
            continue;
        }
        anp=(anp+mo)%mo;
        p[0]=q[k+3]=1;
        for (int i=1;i<=k+2;i++) p[i]=p[i-1]*(n-i)%mo;
        for (int i=k+2;i>=1;i--) q[i]=q[i+1]*(n-i)%mo;
        ans=0;
        for (int i=1;i<=k+2;i++)  {
         ppp=p[i-1]*q[i+1]%mo*ni[k+2-i]%mo*ni[i-1]%mo;
         if (((i&1))^((k&1))) ppp=mo-ppp;
         ans=(ans+ppp*anw[i])%mo; }
        printf("%lld\n",ans);
    }
}

 

posted @ 2018-04-11 18:59  泪寒之雪  阅读(295)  评论(0编辑  收藏  举报