首页 > 其他分享 >拉格朗日插值学习笔记

拉格朗日插值学习笔记

时间:2024-04-20 15:35:08浏览次数:22  
标签:拉格朗 fs 插值 res ll ne 笔记 int prod

拉格朗日插值学习笔记

应用

众所周知,在平面直角坐标系中,对于任意的 \(n\) 个点,都一定有一个不超过 \(n-1\) 次的函数与之相对应。拉格朗日插值适用于求解这 \(n\) 个点对应的函数。

思路

考虑给定的 \(n\) 个点的坐标表示为 \((x_i,y_i)\),不难构造出如下函数:

\[f(x)=\sum_{i=1}^{n}y_ig_i(x) \]

那么此时只需要构造出符合要求的 \(g_i\) 即可。不难发现,为了使 \(f\) 符合条件,\(g_i\) 应该满足:

\[\forall n\in x,g_i(n)=\left\{\begin{matrix}1&n=x_i\\0&n\ne x_i\end{matrix}\right. \]

其中,\(x\) 表示所有 \(x_i\) 构成的集合。不难发现,当 \(n\ne x_i\) 时函数值为 \(0\),说明该函数 \(g_i(x)\) 一定有因式 \((x-x_j)(i\ne j)\),因此不难看出 \(g_i(x)\) 应当有因式 \(\prod_{j\ne i}(x-x_j)\)。又因为当 \(n=x_i\) 时,函数值为 \(0\),不难构造出:

\[g_i(n)=\frac{\prod_{j\ne i}(n-x_j)}{\prod_{j\ne i}(x_i-x_j)} \]

如此就构造出了符合条件的函数,此时可以 \(O(n^2)\) 求解。在单次求解的时候可以采用。

不妨进行进一步转换,令 \(t_i=\frac{y_i}{\prod_{j\ne i}(x_i-x_j)}\),不难看出,\(f(x)=t_i\prod_{j\ne i}(x-x_j)\)。不妨计算出 \(\prod_{i=1}^{n}(x-x_i)\) 后将对应项除掉,接着利用多项式乘法算出每一次项前的系数后,就可以按照多项式加法的方式 \(O(n)\) 求解。这样的方式适用于多组查询或需要求出函数对应项系数的情况。

代码

\(O(n^2)\) 写法

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N=2e3+5,M=998244353;

int n,k;
int x[N],y[N];

ll QuickPow(ll a,int b){
    ll res=1;
    while(b>0){
        if(b&1)res=res*a%M;
        a=a*a%M;
        b>>=1;
    }
    return res;
}

ll Lagrange(int x[],int y[],int X){
    ll res=0;
    for(int i=1;i<=n;i++){
        ll l_i=1;
        for(int j=1;j<=n;j++){
            if(i!=j)l_i=l_i*(X-x[j])%M*QuickPow(x[i]-x[j],M-2)%M;
        }
        res=(res+l_i*y[i]%M)%M;
    }
    return res;
}

int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);
    printf("%lld",(Lagrange(x,y,k)+M)%M);
    return 0;
}

\(O(n)\) 做法

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N=2e3+5,M=998244353;

int n,k;
ll t[N],x[N],y[N],g[N],fs[N],f[N];

ll QuickPow(ll a,int b){
    ll res=1;
    while(b>0){
        if(b&1)res=res*a%M;
        a=a*a%M;
        b>>=1;
    }
    return res;
}

void Init(){
    for(int i=0;i<n;i++){
        t[i]=1;
        for(int j=0;j<n;j++){
            if(i==j)continue;
            t[i]=t[i]*(x[i]-x[j])%M;
        }
        t[i]=QuickPow(t[i],M-2)*y[i]%M;
    }
    fs[0]=1;
    for(int i=0;i<n;i++){
        for(int j=n-1;j>0;j--)fs[j]=(fs[j-1]+fs[j]*(M-x[i])%M)%M;
        fs[0]=fs[0]*(M-x[i])%M;
    }
    for(int i=0;i<n;i++){
        ll inv=QuickPow(M-x[i],M-2);
        g[0]=fs[0]*inv%M;
        for(int j=1;j<n;j++)g[j]=(fs[j]-g[j-1])*inv%M;
        for(int j=0;j<n;j++)f[j]=(f[j]+t[i]*g[j]%M)%M;
    }
    return ;
}

ll Lagrange(ll X){
    ll res=0,Pow=1;
    for(int i=0;i<n;i++){
        res=(res+Pow*f[i]%M)%M;
        Pow=Pow*X%M;
    }
    return res;
}

int main(){
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)scanf("%lld%lld",&x[i],&y[i]);
    Init();
    printf("%lld",(Lagrange(k)+M)%M);
    return 0;
}

标签:拉格朗,fs,插值,res,ll,ne,笔记,int,prod
From: https://www.cnblogs.com/DycBlog/p/18147737

相关文章

  • 算法中的变形金刚——单纯形算法学习笔记
    目录阅读本文你将会知道线性规划简介线性规划的标准形一般型转标准型<与≤线性规划的松弛形标准型转松弛形单纯形算法基本可行解如何判断最优旋转操作如何通过旋转更新解?退化与布兰德规则基本不可行解单纯形算法的几何意义单纯形算法的时间复杂度分析线性规划问题有更优的做法吗......
  • FFmpeg开发笔记(十五)详解MediaMTX的推拉流
    ​MediaMTX是个开源的轻量级流媒体服务器,它的安装过程参见《FFmpeg开发实战:从零基础到短视频上线》一书的“10.2.2 FFmpeg向网络推流”。MediaMTX下载后的压缩包包括可执行程序mediamtx.exe和配置文件mediamtx.yml,看起来非常简约,但它提供的流媒体服务一点也没缩水。双击mediamtx......
  • 基础 IO (Linux学习笔记)
    基础IO1.重谈文件空文件在磁盘也要占据空间文件=内容+属性文件操作=对文件内容+对属性or对文件内容加属性标定一个文件,必须使用文件路径加文件名【唯一性】如果没有指明对应得文件路径,默认是在当前路径下进行文件访问当写了一个跟文件操作有关得程序,编译后,文件......
  • 背包(笔记合集)
    一般代码只是例子,具体使用依据题目来,DP是一种思想,代码都以属性为最大值等等为例子01背包最基本的背包简单说就是有n个物品和容量为m的包,求其max/min/方案数等等即属性一般转移方程为f[i][j]意思为在前i个里容量为j的情况下的要求的属性(可忽略)一般这里的转移是在f[i][j],......
  • Asp-Net-Core开发笔记:使用alpine镜像并加入健康检查
    前言使用docker部署AspNetCore应用已经是标配了,之前我一直使用mcr.microsoft.com/dotnet/aspnet:8.0这类镜像,简单粗暴,不过可以使用alpine进一步优化镜像大小。很多开源工具的docker都有健康检查,这次我顺便也给加上了。添加健康检查注册服务builder.Services.AddHea......
  • 射影几何学笔记
    给大家拉坨大的。在中学阶段,我们就研究过欧几里得平面上的几何。在初中阶段我们学习了平移与旋转,在高中阶段我们学习了仿射,这些几何变换有一个共同点:保持共线三点与共点三线在变换后仍共线或共点。然而在生活中,除了这些变换以外,还有更一般的变换也拥有这个性质:比如,我们在空中对着......
  • 高斯消元学习笔记——P304题解
    如果你觉得这篇太啰嗦问题[SDOI2006]线性方程组题目描述已知\(n\)元线性一次方程组。\[\begin{cases}a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=b_1\\a_{2,1}x_1+a_{2,2}x_2+\cdots+a_{2,n}x_n=b_2\\\cdots\\a_{n,1}x_1+a_{n,2}x......
  • java spring boot 2 开发实战笔记
    本案例是java spingboot 2.2.1  第一步搭建环境:安装依赖由于我们公司项目是1.8环境不能乱,我现在自己的电脑是1.8环境,所以本次整理的boot代码也只能用1.8boot版本为:2.2.1,新建项目后,在xml文件中复制上以下代码xml配置,最精简运行起来的  需要配置一个数据库,8.0以......
  • 畅捷通T+升级笔记
    笔者因安全问题升级畅捷通T+过程失败,几处经验记录于下:不保证跨级升级的成功:在运行的低版本T+上安装高版本补丁包时,除安装文件之外,还须进行数据库升级。数据库的升级是由安装的高版本升级工具执行的,而该过程可能出错,例如尝试迁移一个不存在的数据表。笔者认为,这是由于安装的补丁......
  • day16_我的Java学习笔记 (Set、案例、Collections、Map、集合嵌套)
    1.Set系列集合1.1Set系列集系概述1.2HashSet元素无序的底层原理:哈希表JDK1.7HashSet原理解析:JDK1.8HashSet原理解析:1.3HashSet元素去重复的底层原理Set集合去重复的原因,先判断哈希值,再判断equals重写equals()和HashCode()方......