拉格朗日插值法
Posted wxq1229
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拉格朗日插值法相关的知识,希望对你有一定的参考价值。
拉普兰德 拉格朗日差值法,它可以通过(n)个点来构造出一个(n-1)次多项式(f(x))(恩。应该是最多(n-1)次,因为有些高次项的系数可能是(0))。
8说了。。。康题:P4781 【模板】拉格朗日插值
题意:给(n)个点((x_1,y_1),dots,(x_n,y_n)),你要构造出一个多项式(f(x)),使得(forall 1le i le n,f(x_i) = y_i),再给一个(k),你需要输出(f(k))的值。
然后拉格朗日差值这个神仙东西就横空出世了~
它的想法就是我是否能构造出(n)个多项式(ell_1(x),ell_2(x),dots,ell_n(x)),使得(forall 1le i le n),有
[
ell_i(x_j) = egin{cases}1 quad (j = i) \0 quad (j
ot= i)end{cases}
]
(对其他的(x)并没有要求)
那么结论就是显然可以,并且
[
ell_{i}(x) = prodlimits_{j
ot= i} frac{x - x_j}{x_i - x_j} quad (1le i,j le n)
]
这个显然是对的吧!
当(x = x_i)时,(frac{x - x_j}{x_i - x_j} = frac{x_i - x_j}{x_i - x_j} = 1),所以后面的所有因式都是(1),他们的乘积自然也是(1)。
当(x = x_k (k ot= i))(em...这里的(k)和题面上的不是同一个人),显然会有一个不等于(i)的(j),使得(x_k - x_j = 0),换句话说会有一个因式满足(frac{x - x_j}{x_i - x_j} = 0)。
然后再看回来,既然我们构造出了(ell_{i}(x)),那么(f(x))很好构造吧
[
f(x) = sumlimits_{i = 1} ^ n y_i ell_{i}(x) = sumlimits_{i = 1} ^ n y_i prodlimits_{j
ot= i} frac{x - x_j}{x_i - x_j}
]
根据(ell_{i}(x))的性质,容易验证(f(x_1) = y_1, f(x_2) = y_2,dots,f(x_n) = y_n)。
妙啊~~
好,然后看一下板子题的范围(1 le n le 2 imes 10^3),恩,直接把(k)代进去,算就完了,复杂度$ O(n^2)$
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int P=998244353;
inline int fpow(int a,int b){
int ret=1; for (;b;b>>=1,a=1ll*a*a%P) if (b&1) ret=1ll*ret*a%P;
return ret;
}
#define normal(x) (((x)%P+P)%P)
#define inv(x) (fpow((x),P-2))
const int N=2010;
int lagrange(int *x,int *y,int n,int k){
int ans=0;
for (int i=1;i<=n;i++){
ll tmp=y[i]%P;
for (int j=1;j<=n;j++) if (j!=i)
tmp=1ll*tmp*inv(normal(x[i]-x[j]))%P*normal(k-x[j])%P;
ans=(ans+tmp)%P;
}
return ans;
}
int x[N],y[N],K,n;
int main(){
scanf("%d%d",&n,&K);
for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
printf("%d
",lagrange(x,y,n,K));
return 0;
}
以上是关于拉格朗日插值法的主要内容,如果未能解决你的问题,请参考以下文章