拉格朗日插值浅谈

Posted ylwtsq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拉格朗日插值浅谈相关的知识,希望对你有一定的参考价值。

题目大意:

给你n个点((x[i],y[i])),请你用这n个点构造一个(n-1)次多项式(f(x)),给定一个数(k),求出(f(k))的值.?

solution:

本题(n)的规模较小,是拉格朗日插值的模板题.拉格朗日插值的具体思路如下:

我们的目标是构造一个函数,使得对于所有的(i in [1,n]),有(f(x[i])=y[i]),于是一个非常自然的想法便产生了:我们可以构造(n)个函数,使得(f_{i}(x[i])=y[i],f_{i}(x[j])=0(j ot= i)),然后将这(n)个函数相加即可.那么,如何构造这(n)个函数呢?

下面我们来看一条神奇的式子,它将向我们展示如何构造这若干个函数

? (f_{i}(x)=frac{Pi_{j ot=i}(x-x_{j})}{Pi_{j ot=i}(x_{i}-x_{j})} cdot y[i])

?手动带入分析可知,这个式子符合我们的要求.于是乎,接下来我们利用这个式子实现拉格朗日插值:

(f(x)=sum_{i=1}^{n}frac{Pi_{j ot=i}(x-x_{j})}{Pi_{j ot=i}(x_{i}-x_{j})}cdot y_{i})

(Pi_{i=1}^{n}(x-x_{i}))提出,我们可以得到最终的拉格朗日插值式:

(f(x)=Pi_{i=1}^{n}(x-x_{i})cdot[sum_{i=1}^{n}frac{y_{i}}{(x-x_{i})cdotPi{j ot=i}(x_{i}-x_{j})}])

此式复杂度为(O(n^{2}))

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#define R register
#define next kdjadskfj
#define debug puts("mlg")
#define mod 998244353
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writeln(ll x);
inline void writesp(ll x);
ll n,k;
ll Ans1,Ans2,ans;
ll x[2010],y[2010];
inline ll Qpow(ll _,ll __){ll ___=1;for(;__;__>>=1){if(__&1) ___*=_,___=Mod(___);_*=_,_=Mod(_);}return ___;}
inline ll inv(ll _){return Mod(Qpow(_,mod-2));}

int main(){
	writeln(sizeof(int));
	n=read();k=read();
	Ans1=1;
	for(R ll i=1;i<=n;i++){
		x[i]=read();y[i]=read();
		Ans1*=Mod(k-x[i]);
		Ans1=Mod(Ans1);
	}
	for(R ll i=1;i<=n;i++){
		ans=1;
		for(R ll j=1;j<=n;j++){
			if(j==i) continue;
			ans*=Mod(x[i]-x[j]);
			ans=Mod(ans);
		}
		ans*=(k-x[i]);
		ans=Mod(ans);
		Ans2+=Mod(y[i])*inv(ans);
		Ans2=Mod(Ans2);
	}
	writeln(Mod(Ans1*Ans2));
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) t=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar(‘-‘);x=-x;}if(x<=9){putchar(x+‘0‘);return;}write(x/10);putchar(x%10+‘0‘);}
inline void writesp(ll x){write(x);putchar(‘ ‘);}
inline void writeln(ll x){write(x);putchar(‘
‘);}

以上是关于拉格朗日插值浅谈的主要内容,如果未能解决你的问题,请参考以下文章

拉格朗日插值浅谈

拉格朗日插值Python代码实现

拉格朗日插值法

拉格朗日插值方法

python拉格朗日插值

拉格朗日插值公式