拉格朗日插值

​  给你\(n\)个点:\((x_1,y_1),(x_2,y_2),\ldots,(x_n,y_n)\),求经过这\(n\)个点的\(n-1\)次多项式\(L(x)\)

​  直接高斯消元是\(O(n^3)\)的。

\[L(x)=\sum_{i=1}^ny_i\prod_{j=1,j\neq i}^n\frac{x-x_j}{x_i-x_j}=\sum_{i=1}^ny_i\frac{x-x_1}{x_i-x_1}\cdots\frac{x-x_{i-1}}{x_i-x_{i-1}}\frac{x-x_{i+1}}{x_i-x_{i+1}}\cdots\frac{x-x_n}{x_i-x_n} \]

​  设\(A(x)=\prod_{i=1}^n(x-x_i),B_i(x)=\frac{A(x)}{x-x_i},C_i(x)=\frac{B_i(x)}{B_i(x_i)}\)

​  可以看出

\[C_i(x)=\frac{x-x_1}{x_i-x_1}\cdots\frac{x-x_{i-1}}{x_i-x_{i-1}}\frac{x-x_{i+1}}{x_i-x_{i+1}}\cdots\frac{x-x_n}{x_i-x_n}=\begin{cases} 1~~~~(x=x_i)\\0~~~~(x=x_j,j\neq i)\end{cases} \]

​  因为当\(x=x_i\)时每一项的分子都等于分母,当\(x=x_j(j\neq i)\)时有一项的分子为\(0\)

​  那么

\[L(x)=\sum_{i=1}^n y_iC_i(x) \]

​  这样就可以\(O(n^2)\)算出来了。

代码

​  \(t\)个点,插出\(t-1\)次多项式。

void solve()
{
	memset(c,0,sizeof c);
	c[0]=1;
	memset(ans,0,sizeof ans);
	for(i=1;i<=t;i++)
		for(j=t;j>=0;j--)
		{
			(c[j+1]+=c[j])%=p;
			(c[j]=-c[j]*x[i])%=p;
		}
	for(i=1;i<=t;i++)
	{
		memcpy(d,c,sizeof d);
		memset(b,0,sizeof b);
		for(j=t;j>=0;j--)
		{
			b[j]=d[j+1];
			d[j]=(d[j]+d[j+1]*x[i])%p;
			d[j+1]=0;
		}
		ll s=0,px=1;
		for(j=0;j<=t;j++)
		{
			s=(s+px*b[j])%p;
			px=px*x[i]%p;
		}
		s=fp(s,p-2)*y[i]%p;
		for(j=0;j<=t;j++)
			b[j]=b[j]*s%p;
		for(j=0;j<=t;j++)
			ans[j]=(ans[j]+b[j])%p;
	}
}

​  \(n\)个点,求\(f(m)\)

void solve()
{
	ll ans=0;
	for(i=1;i<=n;i++)
	{
		ll s1=1,s2=1;
		for(j=1;j<=n;j++)
			if(j!=i)
			{
				s1=(s1*(m-x[j]))%p;
				s2=(s2*(x[i]-x[j]))%p;
			}
		ans=(ans+y[i]*s1%p*fp(s2,p-2)%p)%p;
	}
}
posted @ 2018-03-05 20:32  ywwyww  阅读(263)  评论(1编辑  收藏  举报