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

[学习笔记]拉格朗日插值

时间:2022-10-13 14:25:03浏览次数:64  
标签:拉格朗 ch limits 插值 笔记 int WR include

对于拉格朗日插值的了解始于知乎上的数列问题:

问: \(1,3,5,7\) 的下一项是什么啊?
答:根据拉格朗日插值公式,可以显然地构造函数

\[\large f(x)=\dfrac{18111}{2}x^4-90555x^3+\dfrac{633885}{2}x^2-452773x+217331 \]

使得 \(f(1)=1,f(2)=3,f(3)=5,f(4)=7\) ,不难发现 \(f(5)=114514\)
也就是说原数列下一项为 \(114514\)

好了说正经的
众所周知,\(n+1\) 个 \(x\) 坐标不同的点可以确定唯一的最高为 \(n\) 次的多项式。
现在给你 \(n+1\) 个点,让你求这个多项式在 \(k\) 处的值
不妨设 \(n\) 次多项式为 \(f(x)\) ,给定 \(n\) 个点的坐标为 \((x_i,y_i)\)
我们有拉格朗日插值公式

\[\Large f(x)=\sum\limits_{i=1}^{n+1}y_i\prod\limits_{j=1,j\neq i}^{n+1}\frac{x-x_j}{x_i-x_j} \]

首先这个是显然正确的:将任意 \(x_i\) 代入,除了第 \(i\) 项的其它所有东西都会因为分子有 \(-x_i\) 而被消去
没了

P4781 【模板】拉格朗日插值

点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001000,INF=1099511627776,mod=998244353;
int n,k;
int x[WR],y[WR];
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
int quick_pow(int a,int b){
    int base=a,res=1;
    while(b){
        if(b&1) res=res*base%mod;
        base=base*base%mod;
        b>>=1;
    }
    return res;
}
int Lagrange(){
    int ans=0;
    for(int i=1;i<=n;i++){
        int up=1,dn=1;
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            up=up*(k-x[j])%mod;
            dn=dn*(x[i]-x[j])%mod;
        }
        ans=(ans+y[i]*up%mod*quick_pow(dn,mod-2)%mod)%mod;
    }
    while(ans<0) ans+=mod;
    return ans;
}
signed main(){
    n=read(),k=read();
    for(int i=1;i<=n;i++) x[i]=read(),y[i]=read();
    printf("%lld\n",Lagrange());
    return 0;
}

如果已知点的横坐标是连续整数,我们可以做到 \(\mathcal{O}(n)\) 插值。
此时 \(x_1=1~,~x_2=2~,~\cdots~,~x_n=n\)
注意到

\[\begin{aligned} f(x)&=\sum\limits_{i=1}^{n+1}y_i\prod\limits_{i\neq j}\frac{x-x_j}{x_i-x_j}\\ &=\sum\limits_{i=1}^{n+1}y_i\prod\limits_{i\neq j}\frac{x-j}{i-j}\\ \end{aligned} \]

那么显然地,分子为

\[\frac{\prod\limits_{k=1}^{n+1}(x-k)}{x-i} \]

分母可以拆成两段算,为

\[(-1)^{n-i+1}(i-1)!(n+1-i)! \]

至此,原式化为

\[f(x)=\sum\limits_{i=1}^{n+1}y_i\frac{\prod\limits_{k=1}^{n+1}(x-k)}{(x-i)(-1)^{n-i+1}(i-1)!(n+1-i)!} \]

可以通过预处理的方法达到 \(\mathcal{O}(n)\) 的复杂度
CF622F The Sum of the k-th Powers
经典题目
首先我们知道自然数的 \(k\) 次幂之和一定是一个 \(k+1\) 次的多项式
可以处理出前 \(k+2\) 项之和然后直接插出来

点击查看代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=1001000,INF=1099511627776,mod=1e9+7;
int n,k;
int y;
int ans;
int fl[WR],fr[WR],f[WR];
int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    return s*w;
}
int quick_pow(int a,int b){
    int base=a,res=1;
    while(b){
        if(b&1) res=res*base%mod;
        base=base*base%mod;
        b>>=1;
    }
    return res;
}
signed main(){
    n=read(),k=read();
    f[0]=fl[0]=fr[k+3]=1;
    for(int i=1;i<=k+2;i++) fl[i]=fl[i-1]*(n-i)%mod;
    for(int i=k+2;i;i--) fr[i]=fr[i+1]*(n-i)%mod;
    for(int i=1;i<=k+2;i++) f[i]=f[i-1]*i%mod;
    for(int i=1;i<=k+2;i++){
        y=(y+quick_pow(i,k))%mod;
        int up=fl[i-1]*fr[i+1]%mod;
        int dn=f[i-1]*f[k+2-i]%mod*((k-i)&1?-1ll:1ll);
        ans=(ans+y*up%mod*quick_pow(dn,mod-2)%mod)%mod;
    }
    while(ans<0) ans+=mod;
    printf("%lld\n",ans);
    return 0;
}

标签:拉格朗,ch,limits,插值,笔记,int,WR,include
From: https://www.cnblogs.com/WintersRain/p/16787440.html

相关文章

  • SQL封装库学习笔记1.0
    自用学习写的封装库使用方法:Nuget中搜索HNGYSql1.查询数据方法publicstringCommandSelect(stringconnectionString,stringcommandString)connectionString:所连......
  • 第四章学习笔记——并发编程(20201217王菁)
    并发编程  在早期,大多数计算机只用一个处理组件,称为处理器或中央处理器(CPU)。并行算法是一种计算方法,它会尝试使用多个执行并行算法的处理器更好地解决问题。并行计算......
  • tf.py_func的一些使用笔记
    tensorflow.py_func是TensorFlow1.x版本下的函数,在TensorFlow.2.x已经不建议使用了,但是依然可以通过tf.compat.v1.py_func的方式来进行调用。 可以说TensorFlow1.x下的p......
  • 学习笔记7
    第四章并发编程教材学习内容总结本章论述了并发编程,介绍了并行计算的概念,指岀了并行计算的重要性;比较了顺序算法与并行算法,以及并行性与并发性;解释了线程的原理及其相......
  • C语音课堂笔记
    2022-10-13为了让计算机更好的帮助人们工作,于是人们设计出了计算机语言。包括(C/C++/JAVA/Python/Go)。其中,C语言被广泛应用于底层软件的开发。(电脑称为计算机的硬件,由操作......
  • 【复习(雾)笔记】差分/树上差分
    差分/树上差分(雾)前言说实话,写这东西挺迷的,按道理说这玩意我应该会,但是做题的时候又不会,跟新学一样,就离谱。差分这东西就挺神奇的,前后加一减一就能维护区间。开始觉得......
  • 【笔记】裴蜀定理
    裴蜀定理:\[\foralla,b\in\mathbb{Z},\existsx,y\in\mathbb{Z},ax+by=\gcd(a,b)\]要求\(x,y\)不同时为\(0\)。推论:\[\begin{gathered}\text{对于}a,b\in......
  • 记录 debian intel nvidia 笔记本安装显卡驱动详细过程
    目录识别显卡检测并安装显卡驱动配置/etc/X11/xorg.conf/etc/lightdm/display_setup.sh/etc/lightdm/lightdm.conf重启系统,完成所有配置检测结果以下步骤全部根据官方文档......
  • 【博学谷学习记录】超强总结,用心分享 | MySQL的锁_笔记
    目录全局锁表级锁表级锁-表锁表级锁-元数据锁表级锁-IS(意向共享锁)与IX(意向排他锁)行级锁间隙锁例子临键锁和记录锁例子全局锁概念:全局锁就是对整个数据库实例加......
  • 进制转换课堂笔记
    n进制转十进制:(278)n->(2*n^2+7*n^1+8*n^0)10十进制转二进制:(197)10->方法一:辗转相除197/2....198/2......049/2.....124/2.....012/2......0......