拉格朗日插值

插值
已知平面直角坐标系上的n个点,找出一个函数f(x)过这n个点,这样的函数有无限多个。
拉格朗日插值
首先他构造了n个函数,第i个是fi(x)={yix=xi0x=xj(ji)。对于其余的x,我们并不关心。
这样我们可以得出fi(x)=yi×ji(xxj)ji(xixj)
最终可以得出答案 f(x)=i1nfi(x)
例题:
abc137F
代码

#include<iostream>
#define int long long
using namespace std;
int p;
int a[3010];
int b[3010];
int c[3010];
int d[3010];
int ksm(int x,int y){
	int ans=1;
	while(y){
		if(y%2==1){
			ans=ans*x%p;
		}
		x=x*x%p;
		y/=2;
	}
	return ans;
}
int inv[3010];
signed main(){
	cin>>p;
	for(int i=1;i<p;i++){
		inv[i]=ksm(p-i,p-2);
	}
	for(int i=0;i<p;i++){
		cin>>a[i];
	}
	b[0]=1;
	for(int i=0;i<p;i++){
		for(int j=p;j>=0;j--){
			b[j]=b[j]*(p-i)%p;
			if(j!=0){
				b[j]=(b[j]+b[j-1])%p;
			}
		}
	}
	c[0]=1;
	for(int i=1;i<p;i++){
		for(int j=p-1;j>=0;j--){
			c[j]=c[j]*(p-i)%p;
			if(j!=0){
				c[j]=(c[j]+c[j-1])%p;
			}
		}
	}
	int k=1;
	for(int j=1;j<p;j++){
		k=k*(p-j)%p;
	}
	k=ksm(k,p-2)*a[0]%p;
	for(int j=0;j<p;j++){
		d[j]=(d[j]+c[j]*k)%p;
	}
	for(int i=1;i<p;i++){
		for(int j=0;j<p;j++){
			c[j]=b[j];
		}
		for(int j=0;j<p;j++){
			c[j]=c[j]*inv[i]%p;
			if(j!=p-1){
				c[j+1]=(c[j+1]-c[j]+p)%p;
			}
		}
		k=1;
		for(int j=0;j<p;j++){
			if(i!=j){
				k=k*(i-j+p)%p;
			}
		}
		k=ksm(k,p-2)*a[i]%p;
		for(int j=0;j<p;j++){
			d[j]=(d[j]+c[j]*k)%p;
		}
	}
	for(int i=0;i<p;i++){
		cout<<d[i]<<" ";
	}
	return 0;
}
posted @   zzzzzz2  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示