洛谷 P4781 【模板】拉格朗日插值(拉格朗日插值法,逆元)

传送门


拉格朗日插值法

帅气的英文名:Lagrange………
看起来很厉害的名字是用来干什么的呢?
简单点说,就是给你n个点,你就可以确定一个n次多项式。
设这n个点分别为:
\((x_1,y_1)(x_2,y_2)(x_3,y_3)\cdots\cdots(x_n,y_n)\)
则公式为:

\[f(i)=\sum_{i=1}^n y_i\prod_{i\ne j}\frac{(k-x_j)}{x_i-x_j} \]

你把每个x带进去会巧妙的发现都成立。
然后对于求x=k时的值,只需把分子乘上分母的逆元即可。(因为模数是个大质数,所以可直接费马小定理)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=2005;
const int mod=998244353;
int n;
long long k,x[maxn],y[maxn],ans;
long long fastpower(long long a,long long b){
	if(b==0) return 1;
	if(b==1) return a%mod;
	long long res=fastpower(a,b/2);
	if(b&1) return res*res%mod*a%mod;
	return res*res%mod;
}
int main(){
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&x[i],&y[i]);
	}
	for(int i=1;i<=n;i++){
		long long nx=y[i],ny=1;
		for(int j=1;j<=n;j++){
			if(i==j) continue;
			nx=nx*(k-x[j])%mod;
			ny=ny*(x[i]-x[j])%mod;
		}
		nx=nx*fastpower(ny,mod-2)%mod;
		ans=(ans+nx)%mod;
	}
	printf("%lld",(ans+mod)%mod); 
	return 0;
}
posted @ 2021-05-24 23:04  尹昱钦  阅读(89)  评论(0编辑  收藏  举报