zoukankan      html  css  js  c++  java
  • [多项式学习笔记1]拉格朗日插值定理

    [多项式学习笔记1]拉格朗日插值定理

    算法简介

    拉格朗日插值法是以法国18世纪数学家约瑟夫·拉格朗日命名的一种多项式插值方法。

    适用问题

    拉格朗日插值定理主要是用来解决下面这样的问题:

    给出 n 个点 (xi,yi)(保证 xi 互不相同),要求找出一个过所有点的多项式函数 f(x)。 

    显然最直观的方法是采用高斯消元,但高斯消元时间复杂度较高且有精度误差

    这时候就可以考虑用拉格朗日插值定理了

    算法流程

    显然对于每个点,我们尝试找出一个函数 fi(x),使得 fi(xi) = yi, 并且对于其他的所有横坐标 xj(j!=i) 有 fi(xj) = 0。那么把 n 个 fi(x) 加起来就能得到要求的函数 f(x) 了

    可以推出式子:

     时间复杂度 O(n^2)

    代码(luogu模板)

    #include<bits/stdc++.h>
    
    #define ll long long
    
    using namespace std;
    
    inline ll read()
    {
        ll f = 1 , x = 0;
        char ch;
        do
        {
            ch = getchar();
            if(ch=='-') f=-1;
        } while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    const int MAXN = 2000 + 10;
    const ll MOD = 998244353;
    
    inline ll Pow(ll a,ll b)
    
    {
        ll ans = 1,mul = a;
        while(b)
    
        {
            if(b&1) ans = (ans * mul) % MOD;
            mul = (mul * mul)%MOD;
    
            b>>=1;
    
        }
        return ans;
    }
    
    inline ll inv(ll a)
    {
        return Pow(a,MOD-2);
    }
    
    ll n,k;
    ll x[MAXN],y[MAXN];
    ll ans;
    
    int main()
    {
        n = read(),k = read();
        for(int i=1;i<=n;i++) x[i] = read(),y[i] = read();
        for(int i=1;i<=n;i++)
        {
            ll res1 = y[i] % MOD;
            ll res2 = 1;
            for(int j=1;j<=n;j++)
    
            {
                if(i == j) continue;
                res1 = (res1 * (k - x[j]%MOD + MOD)%MOD)%MOD;
                res2 = (res2 * ((x[i] - x[j]%MOD + MOD)%MOD))%MOD;
            }
            ans = (ans + (res1 * inv(res2) % MOD)%MOD) % MOD;
        }
        cout << ans << endl;
    }

    拉格朗日插值定理的扩展

    • 当X取值连续时,可以通过记录前缀和和后缀和做到线性时间复杂度
    • 重心拉格朗日插值定理:
    拉格朗日插值法的公式结构整齐紧凑,在理论分析中十分方便,然而在计算中,当插值点增加或减少一个时,所对应的基本多项式就需要全部重新计算,
    于是整个公式都会变化,非常繁琐
    。这时可以用重心拉格朗日插值法

      将拉格朗日插值定理变形为:

      

      其中 g =

             

      然后另 Ti =

             

      当增加一个点时直接增加ti即可

  • 相关阅读:

    链表
    队列
    稀疏数组
    SQL——流程控制
    SQL——存储过程与函数
    SOA
    MVC模式
    《一线架构师实践指南》--阅读笔记三
    《一线架构师实践指南》-阅读笔记二
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/12369216.html
Copyright © 2011-2022 走看看