因为n次方的函数图像可以有n+1个点确定(比如说y=kx+b就只用两个点确定,y= ax2+bx+c ,只用三个点就可以确定),所以个n次方的方程给你n+1个x或者y就能确定这个方程。拉格朗日插值法就可以把这n+1个对应的值插进一个方程,然后给一个x,可以求出y。比如y=3x+2,给你(x=1,y=5;x=4,y=14)那么随意询问一个x,用拉格朗日插值法就可以求出对应的y。
li(x)=yi∏nj=1,j≠ix−xjxi−xj (x是代进去的数)
首先给你n个x,和n个对应的y。(x[i],y[i])
有一个公式 y=∑ni=1li(x)=∑ni=1yi∏nj=1,j≠ix−xjxi−xj
比如说x1=1,y1=5;x2=4,y2=14
那么我们询问x=15时,y=?
y=y1∗15−x2x1−x2+y2∗15−x1x2−x1
算出来后,y=47
我们可以发现拉格朗日插值法基本多项式 li(x) 在x=x[i]时, li(x)=yi∗1=yi ,但是在 li(x,x≠i) 是,如果x=x[j] (j ≠ i)时, li(x)=yi∗0=0 。最后求和一下,如果带进去的x是x[i] (1,2,3,4..n)(给出的那些点)中的某个数,那么 ∑ni=1li(x)=yi 。因为一共给了n个点得坐标,n个对应的值可以确定一个n-1次的多项式函数,而 ∑ni=1li(x) 都会得到对应的值,所以就可以确定这个函数,那么随意带进去一个x都会返回对应的y。
如果要求多项式的系数,可以把 ∑ni=1li(x)=yi 展开,不过有些麻烦。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int x,i,j,k,l,t,n,m,a[100000],b[10000];//a是x,b是y
double temp,ans;
int main(){
scanf("%d",&n);
fo(i,1,n){
scanf("%d%d",&a[i],&b[i]);
}
scanf("%d",&x);
fo(i,1,n){
temp=b[i];
fo(j,1,n){
if(i==j) continue;
temp*=(x-a[j]);
temp/=(a[i]-a[j]);
}
ans+=temp;
}
printf("%.5lf",ans);
}
拉格朗日插值法如果要在(mod p)意义下进行的话,那么p只能是质数。
如果要mod非质数的话,那么就要用牛顿插值法。