拉格朗日插值法

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;
}

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

拉格朗日插值方法

python拉格朗日插值

拉格朗日插值法求2的平方根

拉格朗日插值公式

拉格朗日插值法理论误差怎么得的

拉格朗日插值公式