爱德华差值法?(卡格朗日差值法)

前(che)言(dan)

拉格朗日插值法最早被英国数学家爱德华·华林于1779年发现,不久后(1783年)由莱昂哈德·欧拉再次发现。1795年,拉格朗日在其著作《师范学校数学基础教程》中发表了这个插值方法,从此他的名字就和这个方法联系在一起。

所以我把拉格朗日插值法叫做爱德华插值法

那么这个东西可以做什么呢?
知道一个 \(N\) 次多项式函数上的 \(N+1\) 个不同的点就可以求得这个 \(N\) 次多项式。
或者说给出 \(N+1\) 个点 \((x_i, y_i)\)(保证 \(x_i\) 互不相同),要求找出一个过所有点的多项式函数 \(f(x)\)
这个过 \(N+1\) 个点的 \(N\) 次多项式是唯一的。N+1点确定一条直线
时间复杂度 \(O(n^2)\)

原理

拉格朗日插值法这个名字听起来很厉害。但是原理简单得让人吃惊。
对于每个点,我们尝试找出一个函数 \(f_i(x)\),使得 \(f_i(x_i) = y_i\),并且对于其他的所有横坐标 \(x_j(j\neq i)\)\(f_i(x_j) = 0\)。那么把 \(n\)\(f_i(x)\) 加起来就能得到要求的函数 \(f(x)\)
那么如何找到函数 \(f_i(x)\) 呢?
\[f_i(x) = y_i∏_{j\neq i}\frac{x − x_j}{x_i − x_j}\]
发现当 \(x=x_i\) 的时候连乘的每一项都是1所以 \(∏_{j\neq i}\frac{x − x_j}{x_i − x_j}=1\),当 \(x=x_j\) 的时候连乘至少有一项为0 \(∏_{j\neq i}\frac{x − x_j}{x_i − x_j}=0\)
进而得出要求的函数 \(f(x)\) 为:
\[f(x) = \sum _{i=1}^{n}y_i ∏_{j\neq i}\frac{x − x_j}{x_i − x_j}\]
然后呢?就结束了呀!

时间复杂度

如果你要求函数某一个点的值,直接把 \(x\) 代进去算,复杂度 \(O(n^2)\)
如果要求多项式系数,直接暴力算是 \(O(n^3)\) 的。
但是考虑预处理出一个多项式 \(P(x) = ∏_{i=1}^{n}(x − x_i)\),每次用 \(P(x)\) 除一下 \(x − x_i\) 就可以得到要求的乘积了。时间复杂度优化到了 \(O(n^2)\)

板子

模板题

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define int long long
const int N=3000;;
const int mod=998244353;
int n,k,x[N],y[N],ans;
int ksm(int x,int b){
    int tmp=1;
    while(b){
        if(b&1)tmp=tmp*x%mod;
        b>>=1;
        x=x*x%mod;
    }
    return tmp;
}
int read(){
    int sum=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    return sum*f;
}
signed main(){
    n=read(),k=read();
    for(int i=1;i<=n;i++)x[i]=read()%mod,y[i]=read()%mod;
    for(int i=1;i<=n;i++){
        int tmp=y[i];
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            tmp=tmp*((k-x[j]+mod)%mod)%mod*ksm((x[i]-x[j]+mod)%mod,mod-2)%mod;
        }
        ans=(ans+tmp)%mod;
    }
    printf("%lld",ans);
    return 0;
}

如果觉得我讲得不好,佷正常!
然后推荐此博客

转载于:https://www.cnblogs.com/Xu-daxia/p/10548611.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值