学习笔记:拉格朗日插值
建议看: cmd:从拉插到快速插值求值
拉格朗日插值
首先我们知道一个事是:
那么当你知道了这
定义:
对于
且
那么对于每个
所以我们获得了拉插公式:
例题:
码
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; #define mk make_pair #define ps push_back #define fi first #define se second const int N=1e6+10,inf=0x3f3f3f3f; const ll mod=998244353,linf=0x3f3f3f3f3f3f3f3f; inline ll read(){ char c=getchar();ll x=0;bool f=0; while(!isdigit(c))f=c=='-'?1:0,c=getchar(); while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar(); return f?-x:x; } inline ll qpow(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=ans*x%mod; x=x*x%mod;y>>=1; } return ans; } int n,K,x[N],y[N]; signed main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); n=read(),K=read(); for(int i=1;i<=n;++i) x[i]=read(),y[i]=read(); ll ans=0; for(int i=1;i<=n;++i){ ll i1=1,i2=1; for(int j=1;j<=n;++j){ if(j==i)continue; i1=i1*(K-x[j])%mod;i2=i2*(x[i]-x[j])%mod; } i1=(i1+mod)%mod;i2=qpow((i2+mod)%mod,mod-2); ans+=i1*i2%mod*y[i]%mod; } cout<<(ans%mod+mod)%mod; }
取值连续时的插值
我们观察式子
对于
例题:
CF622F The Sum of the k-th Powers
码
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define int ll typedef pair<int,int> pii; typedef unsigned long long ull; #define mk make_pair #define ps push_back #define fi first #define se second const int N=1e6+10,inf=0x3f3f3f3f; const ll mod=1e9+7,linf=0x3f3f3f3f3f3f3f3f; inline ll read(){ char c=getchar();ll x=0;bool f=0; while(!isdigit(c))f=c=='-'?1:0,c=getchar(); while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar(); return f?-x:x; } inline ll qpow(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=ans*x%mod; x=x*x%mod;y>>=1; } return ans; } int y[N],n,K,pre[N],hou[N],jc[N]; signed main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); n=read(),K=read(); y[0]=0;jc[0]=1; for(int i=1;i<=K+2;++i){ y[i]=(y[i-1]+qpow(i,K))%mod; jc[i]=jc[i-1]*i%mod; } if(n<=K+2)return cout<<y[n],0; pre[0]=n; for(int i=1;i<=K+2;++i){ pre[i]=pre[i-1]*(n-i)%mod; } hou[K+3]=1; for(int i=K+2;i>=0;--i) hou[i]=hou[i+1]*(n-i)%mod; int ans=0; for(int i=0;i<=K+2;++i){ ans+=(i==0?1ll:pre[i-1])*hou[i+1]%mod*qpow(jc[i],mod-2)%mod*qpow(jc[K+2-i],mod-2)%mod*y[i]%mod*((K+2-i)&1?-1:1); } cout<<(ans%mod+mod)%mod; }
重心拉格朗日插值法
感觉没什么意义,就是瞪了两眼式子省去了不必要的计算。
还是看式子:
我们每加入一个点对于每个
插多项式系数
直接插一个值出来是
还是得改写式子:
首先对于整个式子
有
现在式子长成了
首先
如果只考虑
码
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define int ll typedef pair<int,int> pii; typedef unsigned long long ull; #define mk make_pair #define ps push_back #define fi first #define se second const int N=1e6+10,inf=0x3f3f3f3f; const ll mod=1e9+7,linf=0x3f3f3f3f3f3f3f3f; inline ll read(){ char c=getchar();ll x=0;bool f=0; while(!isdigit(c))f=c=='-'?1:0,c=getchar(); while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar(); return f?-x:x; } inline ll qpow(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=ans*x%mod; x=x*x%mod;y>>=1; } return ans; } int n,x[N],y[N],c[N],f[N],g[N],ff[N]; signed main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); n=read(); for(int i=1;i<=n;++i) x[i]=read(),y[i]=read(); for(int i=1;i<=n;++i){ c[i]=1; for(int j=1;j<=n;++j) if(j!=i)c[i]=c[i]*(x[i]-x[j])%mod; c[i]=(qpow(c[i],mod-2)*y[i]%mod+mod)%mod; } f[0]=1; for(int i=1;i<=n;++i){ for(int j=n-1;j;--j) f[j]=((f[j-1]+f[j]*(-x[i]))%mod+mod)%mod; f[0]=(f[0]*(-x[i])%mod+mod)%mod; } for(int i=1;i<=n;++i){ ll ny=qpow(((-x[i])%mod+mod)%mod,mod-2); g[0]=f[0]*ny%mod;ff[0]=(ff[0]+c[i]*g[0])%mod; for(int j=1;j<n;++j){ g[j]=((f[j]-g[j-1])*ny%mod+mod)%mod; ff[j]=(ff[j]+c[i]*g[j])%mod; } } for(int i=0;i<n;++i) cout<<(ff[i]+mod)%mod<<' '; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章