为了能到远方,脚下的每一步都不能少.|

vanueber

园龄:2年6个月粉丝:0关注:2

拉格朗日插值总结

问题

给定 n 个点,确定一个多项式 f(x)=i=0n1aixi。求 f(k)

解法

拉格朗日插值的核心思想是通过构造 n 个函数,满足第 i 个函数经过 (x1,0),(x2,0),,(xi,yi),,(xn,0),将这 n 个函数的系数累加即可得到原函数。

具体地,有fi(x)=yiijxxjxixj

故原函数

f(x)=i=1nyiijxxjxixj

那么将原问题的 k 代入得:

f(k)=i=1nyiijkxjxixj

这样就在 Θ(n2) 的时间求得一个多项式的值。

练习

P4781 【模板】拉格朗日插值

#include <bits/stdc++.h>
#define int long long

using namespace std;

inline int read()
{
    int w=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        w=(w<<1)+(w<<3)+(ch^48);
        ch=getchar();
    }
    return w*f;
}
void write(int x)
{
    if(x<0) x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

const int mod=998244353;
const int maxn=2e3+10;
int n,k;
int x[maxn],y[maxn];
int qpow(int a,int b,int mod)
{
    int res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

signed main()
{
    n=read(),k=read();
    for(int i=1;i<=n;++i)
    {
        x[i]=read(),y[i]=read();
    }
    int ans=0;
    for(int i=1;i<=n;++i)
    {
        int fz=1,fm=1;
        for(int j=1;j<=n;++j)
        {
            if(j!=i)
            {
                (fz*=(k-x[j]+mod)%mod)%=mod;
                (fm*=(x[i]-x[j]+mod)%mod)%=mod;
            }
        }
        (ans+=fz*qpow(fm,mod-2,mod)%mod*y[i])%=mod;
    }
    cout<<ans<<endl;
    return 0;
}

本文作者:vanueber

本文链接:https://www.cnblogs.com/vanueber/p/18675630

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   vanueber  阅读(1)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起