拉格朗日插值

引入

给出一个函数的点值表达,现在要求函数的系数


拉格朗日插值

一个通俗易懂的讲解

显然我们可以用 \(O(n^3)\) 跑高斯消元

但我们要将它优化到 \(O(n^2)\) 甚至以下

我们考虑设 \(f(x)\) 的点值表达为 \((x_0,y_0),(x_2,y_2)...(x_n,y_n)\)

构造 \(n+1\)\(n\) 次函数 \(f_i(x)\),满足:\(f_i(x_j)=0\ (j\not =i),\ f_i(x_i)=1\)

这样我们就有 \(f(x)=\sum_{i=0}^n y_i f_i(x)\)

显然我们可以这样构造:$f_i(x)=\prod_{j\not = i}\frac{x-x_j}{x_i-x_j} $

所以就有 \(f(k)=\sum_{i=0}^n y_i \prod_{j\not = i}\frac{k-x_j}{x_i-x_j}\)

代码


连续插值

很多情况下,我们得到的 \(x_i\) 在整数域上是连续的,那么我们就有办法优化到 \(O(n)\)

那我们先直接用 \(i\) 表示 \(x_i\)

就有 \(f(k)=\sum_{i=0}^n y_i \prod_{j\not = i}\frac{k-j}{i-j}\)

显然,分子部分 \(k-j\) 可以在求值之前预处理出来

我们观察 \(i-j\) 的部分,不难发现其实是 \((i-1)!\times (n-i)!\),注意到 \((n-i)!\) 的符号

形式化地,我们令 \(pre_i=\prod_{j=0}^i k-j,\ suc_i=\prod_{j=i}^n k-j,\ fac_i=i!\)

\[f(k)=\sum_{i=0}^n (-1)^{n-i} y_i\frac{pre_{i-1}\times suc_{i+1}}{fac_i\times fac_{n-i}} \]


应用

P5667 拉格朗日插值2

直接套公式:

\[\begin{aligned} f(m+k)&=\sum_{i=0}^nf(i)\prod_{i\not = j}\frac{m+k-j}{i-j}\\ &=\sum_{i=0}^nf(i)\frac{(m+k)!}{i!\times (n-i)!\times (m+k-n-1)!\times(m+k-i)}\\ &=\frac{(m+k)!}{(m+k-n-1)!}\sum_{i=0}^n\frac{f(i)}{i!\times (n-i)!}\times \frac{1}{m+k-i} \end{aligned}\]

显然可以是卷积形式 \(A[i]\times B[k-i]\)

但由于 \(i\in [1,n]\),因此可能出现 \(k-i<0\) 的情况,为了能够正常卷积,我们考虑将序列整体向右移 \(n\) 个单位,即 \(i\rightarrow i+n\)

那么卷积后第 \(i+n\) 的系数就是 \(f(m+i)\)

代码

posted @ 2022-04-20 21:17  zuytong  阅读(115)  评论(0编辑  收藏  举报