拉格朗日插值
概念
对于一个 次多项式 ,我们给 个点的坐标 可以唯一确定这个多项式。如果直接暴力解方程组,用高斯消元时间复杂度是 ,有时难以接受。所以我们引入拉格朗日插值算法。
我们构造 。可以发现,对于点 来说,当 时 一定有一次会取到 ,此时后面的式子值为 ;当 时, 值恒为 ,所以值为 即 ,所以有 。所以 为要求的多项式。如果要单点求 ,时间复杂度为 。
luogu P4781【模板】拉格朗日插值
给定 个点,确定其多项式 ,求出 的值 。
模板题,代码如下
#include <iostream>
using namespace std;
const int N=2e3+9,mod=998244353;
typedef long long int ll;
int n,k,x[N],y[N];
ll ans;
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-48,c=getchar();}
return x*f;
}
ll quick_pow(ll x,int y)
{
ll ans=1;
while(y!=0)
{
if(y&1) ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return 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 p=y[i],q=1;
for(int j=1;j<=n;j++)
{
if(i==j) continue;
p=p*(k-x[j])%mod,q=q*(x[i]-x[j])%mod;
}
ans=(ans+p*quick_pow(q,mod-2)%mod)%mod;
}
printf("%lld",(ans+mod)%mod);
return 0;
}
CF622F The Sum of the k-th Powers
给定 ,求 。
比较经典的一道题,首先可以证明原式是一个 次多项式(证明较为复杂,此处略去)。我们设 ,我们要求的就是 。考虑拉格朗日插值,这里要用到一个常用的套路,如果题目中没有给定这 个点,我们可以选取等差数列中连续的 个点。选等差数列有什么好处呢,对于等差数列 ,我们令 ,其中 为公差。我们将 代入到拉格朗日插值的公式中,可以得到
。具体地,我们假设 ,得到 。我们继续化简,
所以我们只需要预处理阶乘的逆元以及 的前缀积 和后缀积 ,便可以 求解后面的式子。然后我们再考虑 ,我们可以先线性筛来预处理 ,然后再做一遍前缀和就可以得到所有的 。所以总时间复杂度为 。
事实上这个式子比较常用,所以建议记住解决方法。若所求的值可以 ,就直接线性筛加前缀和,否则就利用拉格朗日插值求值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)