拉格朗日插值法

本文介绍了拉格朗日插值法,通过构造多项式确保在给定的n+1个点上取到对应的y值。详细阐述了基本思路和连续取值时的处理方法,并提供了相关算法的复杂度分析和洛谷P4781问题的代码参考。
摘要由CSDN通过智能技术生成

拉格朗日插值法

以下内容并完全原创,很多地方引用了 @attack 的博客

拉格朗日插值法就是构造一个多项式,使得恰好在每一个x处取到对应的y
首先,n+1个点(xi,yi)若xi不同,则可以确定唯一的最高幂次不超过n的多项式。而如果题目直接或是间接给出了n+1个点,让我们求由这些点构成的多项式在某一个位置的取值,那么应用拉格朗日插值可以在O(n2 )的时间内解决这一问题


基本内容:

在这里插入图片描述
思路如下:
对于这个函数,要想在k=x[i]的时候取到y[i],并且y[i]仅在这一情况对答案有影响,就要构造出一项K[i]y[i],使得x仅在取到x[i]时K为1,其他情况K[i]为0。
于是,仿照中国剩余定理的思路,有了如下构造方式:
(1)首先,x≠x[i]时K[i]为0,就要让x取到除去x[i]外的任何值都为0,于是有了“累乘‘k-x[j]’”的思路;
(2)其次,如果简单地将y[i]与 累乘‘k-x[j]’ 结合,则x=x[i]时
该项为“累乘x[i]-x[j]",所以需要在每一项下面加上"除以x[i]-x[j]”
(3)最后将每一项加和,得到上式


拓展:x取值连续时的做法

有时候,问题仅要求求解x连续的情况。那么如果仅有一个k值需要代入f(k),就可以用下面的方法将复杂度变为O(n)
在这里插入图片描述
对于分子,维护出k的前缀积和后缀积,即:
在这里插入图片描述
在这里插入图片描述

由于最终求得的值一定为正数,故需判断一下正负号。
如果N-i为奇数,则分母要取负数(因为fac(N-i)表示的是绝对值,N-i为偶数的时候恰好所有负号消掉了)
在这里插入图片描述
(好吧我承认基本上都是复制粘贴)
洛谷P4781代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define il inline
#define re register
il int read()
{
	int s=0,w=1;char c=getchar();
	while(c<'0'||c>'9'){ if(c=='-') w=-1;c=getchar(); }
	while(c>='0'&&c<='9'){ s=(s<<1)+(s<<3)+c-'0',c=getchar(); }
	return s*w;
} 
const int N=2010;
const LL mod=998244353;
int n,K,X[N],Y[N];
LL G=1LL,sum,xx,yy;
il LL exgcd(LL a,LL b,LL &x,LL &y){
	if(b==0){
		x=1LL,y=0;return a;
	}
	LL d=exgcd(b,a%b,x,y);
	LL z=x;x=y,y=z-(a/b)*y;return d;
}
il LL qpow(LL a,LL x){
	LL res=1LL;
	while(x){
		if(x&1) res=(res*a)%mod;
		x>>=1,a=(a*a)%mod;
	}return res%mod;
}
il LL Ni(LL val){
	val=(val%mod+mod)%mod;
	LL GCD=exgcd(val,mod,xx,yy);
	//printf("%lld: %lld\n",val,(xx%mod+mod)%mod);
	//printf("qpow: %lld\n",(qpow(val,mod-2)+mod)%mod);
	return xx;
	//return qpow(val,mod-2);
}
int main()
{
	n=read(),K=read();
	for(re int i=1;i<=n;i++) X[i]=read(),Y[i]=read();
	for(re int i=1;i<=n;i++) G=(G*(K-X[i]))%mod;
	for(re int i=1;i<=n;i++){
		LL mul=Y[i]*Ni(K-X[i])%mod;
		for(re int j=1;j<=n;j++){
			if(i!=j) mul=(mul*Ni(X[i]-X[j]))%mod;
		}
		sum=(sum+mul)%mod; 
	}
	sum=((sum*G)%mod+mod)%mod;
	printf("%lld",sum);
	return 0;
}

end

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值