模板 - 数学 - 多项式 - 拉格朗日插值
已知 \(n+1\) 个点,拟合一个多项式 \(f\) ,求 \(f(x)\) 的值。
拉格朗日插值多项式为: \(f(x)=\sum\limits_{i=0}^{n}y_i\frac{\prod_{j=0,j\neq i}^{n}(x-x_j)}{\prod_{j=0,j\neq i}^{n}(x_i-x_j)}\)
从数组 \(x\) 和 \(y\) 的 \([0,n]\) 共 \(n+1\) 个点,插值出一个 \(n\) 次多项式 \(f\) ,然后求出 \(f(x_i)\) 返回。
int lagrange(int n, int *x, int *y, int xi) {
int ans = 0;
for (int i = 0; i <= n; i++) {
int s1 = 1, s2 = 1;
for (int j = 0; j <= n; j++)
if (i != j) {
s1 = 1ll * s1 * (xi - x[j]) % mod;
s2 = 1ll * s2 * (x[i] - x[j]) % mod;
}
ans = (1ll * ans + 1ll * y[i] * s1 % mod * quick_pow(s2, mod - 2) % mod) % mod;
}
return (ans + mod) % mod;
}
从数组 \(x\) 和 \(y\) 的 \([0,n]\) 共 \(n+1\) 个点,插值出一个 \(n\) 次多项式 \(f\) ,然后求出 \(f(x_i)\) 返回,其中数组 \(x\) 的点需要是连续自然数。
int lagrange(int n, int *x, int *y, int xi) {
int ans = 0;
s1[0] = (xi - x[0]) % mod, s2[n + 1] = 1;
for (int i = 1; i <= n; i++)
s1[i] = 1ll * s1[i - 1] * (xi - x[i]) % mod;
for (int i = n; i >= 0; i--)
s2[i] = 1ll * s2[i + 1] * (xi - x[i]) % mod;
ifac[0] = ifac[1] = 1;
for (int i = 2; i <= n; i++)
ifac[i] = -1ll * mod / i * ifac[mod % i] % mod;
for (int i = 2; i <= n; i++)
ifac[i] = 1ll * ifac[i] * ifac[i - 1] % mod;
for (int i = 0; i <= n; i++)
(ans += 1ll * y[i] * (i == 0 ? 1 : s1[i - 1]) % mod * s2[i + 1] % mod
* ifac[i] % mod * (((n - i) & 1) ? -1 : 1) * ifac[n - i] % mod) %= mod;
return (ans + mod) % mod;
}