拉格朗日插值法

https://www.luogu.com.cn/problem/P4781

给定 \(n\) 个点 \((x_i,y_i)\) 满足 \(x_i\) 互不相同,经过它们可以确定一个 \(n-1\) 次多项式 \(y=f(x)\),构造 \(f(x)\).

考虑构造 \(f_i(x)\) 满足图像经过 \(\begin{cases}(x_j,0),(j\ne i)\\ (x_i,y_j) \end{cases}\),因此 \(f(x) = \sum_{i=1}^{n}{f_i(x)}\).

构造 \(f_i(x)=a\cdot \prod_{j\ne i}{(x-x_j)}\),将 \(f_i(x_i)=y_i\) 代入,得

\[a = \frac{y_i}{\prod_{j\ne i}{(x_i-x_j)}} \]

因此

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

时间复杂度 \(\mathcal{O}(n^2 \log n)\).

//author:kzssCCC

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int MOD = 998244353;

ll qpow(ll a,ll b){
	ll res = 1;
	while (b){
		if (b&1){
			res = res*a%MOD;
		}
		a = a*a%MOD;
		b >>= 1;
	}
	return res;
}

void solve(){
	int n;
	ll k;
	cin >> n >> k;

	vector<ll> X(n+1),Y(n+1);
	for (int i=1;i<=n;i++){
		cin >> X[i] >> Y[i];
	}

	ll res = 0;
	for (int i=1;i<=n;i++){
		ll cur = 1;
		for (int j=1;j<=n;j++){
			if (j==i) continue;
			cur = cur*((k-X[j]+MOD)%MOD)%MOD*qpow((X[i]-X[j]+MOD)%MOD,MOD-2)%MOD;
		}
		res = (res+cur*Y[i]%MOD)%MOD;
	}
	cout << res << '\n';
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int t = 1;
	// cin >> t;
	while (t--) solve();

	return 0;
}
    
posted @ 2026-07-09 13:57  kzssCCC  阅读(5)  评论(0)    收藏  举报