拉格朗日插值

拉格朗日插值

拉格朗日插值主要解决求高次多项式的问题,和求特定的条件限制的多项式。

本文前置知识:多项式除法,线性同余方程中国剩余定理乘法逆元(逆元前置:扩展欧几里得(线性同余方程)或者快速幂(由费马小定理所得)或者线性求逆元)。

主要懂得加粗知识就大概差不多了,感觉好啰嗦,主要想记录一下,懂得这些前置知识学会拉格朗日插值是很轻松的


拉格朗日插值求多项式

\(n\)个点\((x_i,y_i)\),求出过这\(n\)个点的多项式\(f(x)\)

\(n\)\(y_i\)对应着\(n\)\(x_i\),对于每个\(f(y_i)\),有:

\(f(x)\equiv y_i(mod (x-x_i))\)

因为\(f(x)-f(x_i)=(a_0-a_0)+a_1(x^1-x_i^1)+...+a_n(x^n-a^n)\)其中\(a\)位多项式中的系数和常数,所以我们可以得到:

$ \begin{cases} f(x)\equiv y_1\pmod{(x-x_1)}\ f(x)\equiv y_2\pmod{(x-x_2)}\ \cdots\ f(x)\equiv y_n\pmod{(x-x_n)} \end{cases} $​

这是一个一元线性同余方程接下来我们根据中国剩余定理\(x=\sum_{i=1}^k a_ic_i \pmod n\)

可得:$M= M=\prod_{i=1}^n{(x-x_i)},m_i=\dfrac M{x-x_i}=\prod_{j\ne i}{(x-x_j)} $

\(m_i\)​的逆元,然后可得$f(x)=\sum_{i=1}^n{y_i\prod_{j\ne i}{\dfrac {x-x_j}{x_i-x_j}}} $​

这个过程中如果求逆元是用的快速幂\((logn)\)的话时间复杂度为\(O(n^2log n)\).

例题:

【模板】拉格朗日插值

[TJOI2018]教科书般的亵渎

这里给出模板那道题的代码,注意只需要求\(f(k)\)即可不用全部求出。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
const int MN=2e3+100;
int n,k,ans,x[MN],y[MN];

inline int qpow(int a,int b){
	int res=1ll;
	while(b){
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}

inline int inv(int x){return qpow(x,mod-2);}

signed main(){
	scanf("%lld%lld",&n,&k);
	for(int i=1;i<=n;++i)scanf("%lld%lld",&x[i],&y[i]);
	for(int i=1;i<=n;++i){
		int son=y[i]%mod;
		int mom=1ll;
		for(int j=1;j<=n;++j){
			if(i!=j)son=son*(k-x[j])%mod,mom=mom*(x[i]-x[j])%mod;
		}
		ans=(ans+son*inv(mom))%mod;
	}
	printf("%lld\n",(ans%mod+mod)%mod);
	return 0;
}
posted @ 2021-09-06 21:26  fanner_rick  阅读(259)  评论(0)    收藏  举报