bzoj3453: tyvj 1858 XLkxc(拉格朗日插值)
阿新 • • 發佈:2019-01-03
\(f(n)=\sum_{i=1}^ni^k\),這是自然數冪次和,是一個以\(n\)為自變數的\(k+1\)次多項式
\(g(n)=\sum_{i=1}^nf(i)\),因為這東西差分之後是\(f\),所以這是一個\(k+2\)次多項式
同理最後我們要求的也是一個\(k+3\)次多項式
\(f,g\)暴力計算,然後把第三個多項式用拉格朗日插值插出來,最後只要求第三個多項式的點值即可
話說這題模數沒問題啊……為啥得開longlong啊……
//minamoto #include<bits/stdc++.h> #define R register #define int long long #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) using namespace std; const int N=155,P=1234567891; inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;} inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;} inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;} int ksm(R int x,R int y){ R int res=1; for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x); return res; } int f[N],g[N],n,k,a,d,x[N]; int Large(int *f,int n,int k){ if(k<=n)return f[k]; int ty=(n&1)?P-1:1,res=0,tmp=1; fp(i,1,n)tmp=1ll*tmp*(k-i)%P*ksm(i,P-2)%P; fp(i,0,n){ res=add(res,1ll*tmp*ty%P*f[i]%P); tmp=1ll*tmp*(k-i)%P*ksm(k-i-1,P-2)%P*(n-i)%P*ksm(i+1,P-2)%P; ty=P-ty; }return res; } signed main(){ // freopen("testdata.in","r",stdin); int T;scanf("%lld",&T); while(T--){ scanf("%lld%lld%lld%lld",&k,&a,&n,&d); // memset(f,0,sizeof(f)),memset(g,0,sizeof(g)); fp(i,1,k+4)f[i]=add(f[i-1],ksm(i,k)); fp(i,1,k+4)f[i]=add(f[i],f[i-1]); fp(i,0,k+4)g[i]=add(i?g[i-1]:0,Large(f,k+4,add(a,mul(i,d)))); printf("%lld\n",Large(g,k+4,n)); }return 0; }