嘘~ 正在从服务器偷取页面 . . .

浅谈拉格朗日插值法


浅谈拉格朗日插值法

模板题链接P4781 【模板】拉格朗日插值

题意

给定 $n$ 个点 $P_i(x_i,y_i)$ ,将过该 $n$ 个点的最多 $n-1$ 次多项式记为 $f(x)$

给出 $k$ ,求 $f(k) \bmod 998244353$

证明:过 $P_i$ 作垂线交 $x$ 轴于 $H_i(x_i,0)$

构造 $g_i(x),i=1,2,\cdots ,n$ ,使得 $g_i(x)$ 的图像过 $\begin{cases}P_i(x_i,y_i) \[8pt] H_j(x_j,0),j\ne i\end{cases}$

可以发现,$g_i(x) = a \prod_{j\ne i}{(x-x_j)}$ ,其中 $a$ 是未知数

因为 $g_i(x)$ 过 $P_i(x_i,y_i)$ ,代入并整理可得

把 $a$ 代入 $g_i(x)$ 得

把 $k$ 代入即可得

求解时可以先分别求出分子和分母,最后分子乘上分母的逆元即可

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define gc() getchar()
#define pc(a) putchar(a)
#define mod (int)(998244353)
template<typename T>inline void read(T &k)
{
	char ch=gc();T x=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
	k=x*f;
}
template<typename T>inline void write(T k)
{
	if(k<0){k=-k;pc('-');}
	if(k>9)write(k/10);
	pc(k%10+'0');
}
#define MAXN (int)(2e3+5)
int qpow(int a,int b)
{
	int ans=1,base=a;
	while(b)
	{
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans;
}
int inv(int x){return qpow(x,mod-2);}
int n,k,a,b,ans;
int x[MAXN],y[MAXN];
signed main()
{
	read(n);read(k);
	for(int i=1; i<=n; i++)
		read(x[i]),read(y[i]);
	for(int i=1; i<=n; i++)
	{
		a=y[i]%mod,b=1;
		for(int j=1; j<=n; j++) if(i!=j)
		{
			b=(x[i]-x[j]+mod)%mod*b%mod;
			a=(k-x[j]+mod)%mod*a%mod;
		}
		ans=(ans+a*inv(b)%mod)%mod;
	}
	write(ans);pc('\n');
	return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录