拉格朗日插值学习笔记
1.笛卡尔树学习笔记2.基环树学习笔记3.后缀数组学习笔记4.虚树学习笔记5.网络流学习笔记6.线性基学习笔记
7.拉格朗日插值学习笔记
8.杜教筛学习笔记9.数论分块学习笔记10.莫比乌斯反演学习笔记11.广义后缀自动机学习笔记12.后缀自动机学习笔记13.回文自动机学习笔记14.Manacher 学习笔记15.LCT 学习笔记16.Min_25 筛学习笔记17.Min-Max 容斥学习笔记18.位运算卷积学习笔记19.斯特林数学习笔记20.下降幂学习笔记21.普通生成函数学习笔记22.二项式反演学习笔记23.FFT 学习笔记24.原根学习笔记25.替罪羊树学习笔记26.矩阵树定理学习笔记27.高斯消元学习笔记28.LGV 引理学习笔记29.K-D tree 学习笔记30.线段树综合31.2-sat 学习笔记32.凸包学习笔记33.插头 dp 学习笔记34.整体二分学习笔记35.《具体数学》阅读笔记36.辛普森积分学习笔记拉格朗日插值学习笔记
应用
众所周知,在平面直角坐标系中,对于任意的
思路
考虑给定的
那么此时只需要构造出符合要求的
其中,
如此就构造出了符合条件的函数,此时可以
代码
#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;
}
那么可能有人就要说了,我要是需要多次求解,那我不就似了吗,没错,你似了。所以不妨进行进一步转换,令
代码
#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;
}
但也许题目中给出的
代码
void Init(){
f[0]=1;
pw[0]=0;
for(int i=1;i<=k+2;i++){
f[i]=f[i-1]*i%P;
pw[i]=(pw[i-1]+QuickPow(i,k,P))%P;
}
return ;
}
ll Lagrange(ll x,const int M){
pre[0]=nxt[k+3]=1;
for(int i=1;i<=k+2;i++)pre[i]=pre[i-1]*(x-i)%M;
for(int i=k+2;i>=1;i--)nxt[i]=nxt[i+1]*(x-i)%M;
ll res=0,y=0;
for(int i=1;i<=k+2;i++)res=(res+(((k-i)&1)?-1:1)*pw[i]*pre[i-1]%M*nxt[i+1]%M*QuickPow(f[i-1]*f[k+2-i],M-2,M))%M;
return res;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签