[学习笔记]拉格朗日插值法

pre

很早以前就知道这玩意儿,但是一直没有学。。。
然后突然看到了这东西,就顺便学了一下
然后发现十分简单

用途

(众所周知,n阶多项式能用n+1对不同的(x,y)来表示)
能将n阶多项式的点值表达式转换成系数表达式,主要就是用了构造法

实现

这个叫Joseph-Louis Lagrange的神仙把这个多项式分成了n个部分的和
使第 i i i个部分 f i ( x i ) = y i , f i ( x j ) = 0 ( j ≠ i ) f_i(x_i)=y_i,f_i(x_j)=0(j \ne i) fi(xi)=yi,fi(xj)=0(j̸=i)
那么这个多项式 f i f_i fi怎样构造
因为 f i ( x j ) = 0 f_i(x_j)=0 fi(xj)=0
所以多项式 f i f_i fi一定有因式 ( x i − x j ) (x_i-x_j) (xixj)
并且当 x = x i x=x_i x=xi f i ( x i ) = y i f_i(x_i)=y_i fi(xi)=yi
所以我们就构造出了
f i ( x ) = y i × ∏ 1 ≤ j ≤ n , j ≠ i x − x i x j − x i f_i(x)=y_i\times \prod_{1\leq j\leq n,j\ne i}\frac{x-x_i}{x_j-x_i} fi(x)=yi×1jn,j̸=ixjxixxi
最后只要把n个多项式加起来就好了
F = ∑ i = 1 n ( y i ∏ 1 ≤ j ≤ n , j ≠ i x − x i x j − x i ) F=\sum_{i=1}^n(y_i\prod_{1\leq j\leq n,j\ne i}\frac{x-x_i}{x_j-x_i}) F=i=1n(yi1jn,j̸=ixjxixxi)
时间复杂度 O ( n 2 ) \mathcal{O(n^2)} O(n2)

Code

下面是P4781 【模板】拉格朗日插值的代码

#include <cstdio>
#define MOD 998244353
#define N 2010

using namespace std;
typedef long long LL;
LL x[N], y[N];

inline LL qsm(LL x, int y) {
	if (y == 1) return x;
	LL t = qsm(x, y >> 1);
	if (y & 1) return t * t % MOD * x % MOD;
	else return t * t % MOD;
}

int main() {
	int n;
	LL k;
	scanf("%d%lld", &n, &k);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld%lld", &x[i], &y[i]);
	}
	LL nowans = 0;
	for (int i = 1; i <= n; ++i) {
		LL ans = y[i];
		for (int j = 1; j <= n; ++j) {
			if (j != i) {
				ans = ans * (k - x[j]) % MOD * qsm(x[i] - x[j], MOD - 2) % MOD;
			}
		}
		nowans += ans;
		if (nowans < 0) nowans += MOD;
		if (nowans >= MOD) nowans -= MOD;
	}
	printf("%lld\n", nowans);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值