【BZOJ】3453: tyvj 1858 XLkxc 拉格朗日插值（自然数幂和）

【题意】给定k<=123，a,n,d<=10^9，求：

$$f(n)=\sum_{i=0}^{n}\sum_{j=1}^{a+id}\sum_{x=1}^{j}x^k$$

【算法】拉格朗日插值

【题解】参考：拉格朗日插值法及应用 by DZYO

$$\sum_{x=1}^{j}x^k$$

$$g(m)=\sum_{j=1}^{m}\sum_{x=1}^{j}x^k$$

$$f(n)=\sum_{i=0}^{n}g(a+id)$$

#include<cstdio>
#include<cstring>
#include<algorithm>
#define int unsigned int
using namespace std;
const int maxn=150,MOD=1234567891;
int f[maxn],g[maxn],a,b,k,n,mx,fac[maxn],fav[maxn];
int M(int x){return x>=MOD?x-MOD:x;}
int power(int x,int k){int ans=1;while(k){if(k&1)ans=1ll*ans*x%MOD;x=1ll*x*x%MOD;k>>=1;}return ans;}
int calc(int *g,int u){
if(u<=mx)return g[u];//?
int v=1;
for(int i=1;i<=mx;i++)v=1ll*v*(u-i+MOD)%MOD;
int ans=0;
for(int i=1;i<=mx;i++){
int t=1ll*fav[i-1]*fav[mx-i]%MOD;
if((mx-i)&1)t=M(MOD-t);
ans=M(ans+1ll*g[i]*v%MOD*power(M(u-i+MOD),MOD-2)%MOD*t%MOD);
}
return ans;
}
#undef int
int main(){
#define int unsigned int
int T;scanf("%d",&T);
fac[0]=1;for(int i=1;i<=130;i++)fac[i]=1ll*fac[i-1]*i%MOD;
fav[130]=power(fac[130],MOD-2);for(int i=130;i>=1;i--)fav[i-1]=1ll*fav[i]*i%MOD;
while(T--){
scanf("%d%d%d%d",&k,&a,&n,&b);mx=k+5;
g[0]=0;
for(int i=1;i<=mx;i++){
g[i]=g[i-1];
for(int j=1;j<=i;j++){
g[i]=M(g[i]+power(j,k));
}
}
f[0]=calc(g,a);//!!!
for(int i=1;i<=mx;i++){
f[i]=M(f[i-1]+calc(g,M(a+1ll*i*b%MOD)));
}
printf("%d\n",calc(f,n));
}
return 0;
}
View Code

posted @ 2018-04-20 06:54  ONION_CYC  阅读(563)  评论(0编辑  收藏