[BZOJ3453]tyvj 1858 XLkxc:拉格朗日插值

分析

之前一直不知道拉格朗日插值是干什么用的,只会做模板题,做了这道题才明白这个神奇算法的用法。

由题意可知,\(f(x)\)是关于\(x\)\(k+1\)次函数,\(g(x)\)是关于\(x\)\(k+2\)次函数,\(ans(x)\)是关于\(x\)\(k+3\)次函数。

由于点值连续,插值可以做到\(O(n)\),求\(g(x)\)\(ans(x)\)都需要插值,因此时间复杂度为\(O(Tn^2 \log n)。(\)\log$是快速幂的,貌似可以通过预处理逆元优化掉,不过AC这道题已经绰绰有余了。

代码

#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define	irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

const LL MOD=1234567891;
const int MAXN=130;

int k;
LL s,n,d,inv[MAXN],ff[MAXN],gg[MAXN],hh[MAXN];

inline LL qpow(LL x,LL y){
	LL ret=1,tt=x%MOD;
	while(y){
		if(y&1) ret=ret*tt%MOD;
		tt=tt*tt%MOD;
		y>>=1;
	}
	return ret;
}

LL g(LL x){
	if(x<=k+3) return gg[x];
	LL son=1,mot=1;
	rin(i,2,k+3) son=son*(x-i+MOD)%MOD;
	rin(i,2,k+3) mot=mot*(1-i+MOD)%MOD;
	LL ret=0;
	rin(i,1,k+3){
		ret=(ret+gg[i]*son%MOD*qpow(mot,MOD-2))%MOD;
		son=son*qpow(x-(i+1)+MOD,MOD-2)%MOD*(x-i+MOD)%MOD;
		mot=mot*qpow(k+3-i+MOD,MOD-2)%MOD*(MOD-i)%MOD;
	}
	return ret;
}

LL h(LL x){
	if(x<=k+4) return hh[x];
	LL son=1,mot=1;
	rin(i,2,k+4) son=son*(x-i+MOD)%MOD;
	rin(i,2,k+4) mot=mot*(1-i+MOD)%MOD;
	LL ret=0;
	rin(i,1,k+4){
		ret=(ret+hh[i]*son%MOD*qpow(mot,MOD-2))%MOD;
		son=son*qpow(x-(i+1)+MOD,MOD-2)%MOD*(x-i+MOD)%MOD;
		mot=mot*qpow(k+4-i+MOD,MOD-2)%MOD*(MOD-i)%MOD;
	}
	return ret;
}

int main(){
	int T=read();
	while(T--){
		k=read(),s=read(),n=read(),d=read();
		ff[0]=0;
		rin(i,1,k+3) ff[i]=(ff[i-1]+qpow(i,k))%MOD;
		gg[0]=0;
		rin(i,1,k+3) gg[i]=(gg[i-1]+ff[i])%MOD;
		hh[0]=g(s);
		rin(i,1,k+4) hh[i]=(hh[i-1]+g((s+i*d)%MOD))%MOD;
		printf("%lld\n",h(n));
	}
	return 0;
}

/*
5
120 102497463 92989700 20360484
66 105420730 97423975 32388530
95 64109604 78460286 106343540
101 66688000 92566071 49084899
102 120568505 7166048 11911911

948519230
179937457
690200633
382076592
500116309
*/

posted on 2019-02-14 11:46  ErkkiErkko  阅读(217)  评论(0编辑  收藏  举报