zoukankan      html  css  js  c++  java
  • [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
    ",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
    */
    
  • 相关阅读:
    设计模式的分类
    SQL Server 2005 TSQL 学习笔记:排名函数
    JS正则表达式语法
    魅族 “拜产品教”公司的优秀与局限
    jqueryMobile初始化组件
    Loading Scripts Without Blocking
    LabJs学习笔记:分析图
    翻转的css3样式
    IE(IE6/IE7/IE8)支持HTML5标签
    我的空间轨迹!
  • 原文地址:https://www.cnblogs.com/ErkkiErkko/p/10373792.html
Copyright © 2011-2022 走看看