拉格朗日插值相关

本文详细介绍了多项式插值的概念,包括朴素插值方法和拉格朗日插值法,以及如何利用拉格朗日插值法高效计算自然数幂和。通过对自然数幂和公式的推导,结合拉格朗日插值法,实现了多项式插值的高效计算。

一.插值的定义.

插值:给定若干个点(xi,yi)(x_i,y_i)(xi,yi),确定一条函数曲线f(x)f(x)f(x)满足对于所有iii,有f(xi)=yif(x_i)=y_if(xi)=yi的过程称为插值.

多项式插值:给定n+1n+1n+1xix_ixi两两不同的点(xi,yi)(x_i,y_i)(xi,yi),确定一个多项式f(x)=∑i=0naixif(x)=\sum_{i=0}^{n}a_ix^{i}f(x)=i=0naixi满足对于所有iii,有f(xi)=yif(x_i)=y_if(xi)=yi的过程称为插值.

方便起见,接下来若没有说明,则下文所说的所有插值均指多项式插值.


二.朴素插值方法.

根据插值的定义,很容易列出如下方程组:
{a0+a1x0+a2x02+⋯+anx0n=y0a0+a1x1+a2x12+⋯+anx1n=y1⋮a0+a1xn+a2xn2+⋯+anxnn=yn \left\{\begin{matrix} a_0+a_1x_0+a_2x_0^2+\cdots+a_nx_0^n=y_0\\ a_0+a_1x_1+a_2x_1^2+\cdots+a_nx_1^n=y_1\\ \vdots\\ a_0+a_1x_n+a_2x_n^2+\cdots+a_nx_n^n=y_n \end{matrix}\right. a0+a1x0+a2x02++anx0n=y0a0+a1x1+a2x12++anx1n=y1a0+a1xn+a2xn2++anxnn=yn

接下来只需要高斯消元,就可以在O(n3)O(n^3)O(n3)的时间复杂度内求出这个多项式了.


三.拉格朗日插值法.

显然,O(n3)O(n^3)O(n3)的时间复杂度并不令人满意,考虑有没有其他更加优秀的算法.

拉格朗日插值法的思路是构造n+1n+1n+1个基础多项式li(x)l_i(x)li(x)满足:
li(xi)=1j≠i⇒li(xj)=0 l_i(x_i)=1\\ j\neq i\Rightarrow l_i(x_j)=0 li(xi)=1j=ili(xj)=0

然后拉格朗日构造出了这样的基础多项式:
li(x)=∏j≠ix−xjxi−xj l_i(x)=\prod_{j\neq i}\frac{x-x_j}{x_i-x_j} li(x)=j=ixixjxxj

有了这n+1n+1n+1个基础多项式,我们就可以通过它们的线性组合得到f(x)f(x)f(x)
f(x)=∑i=0nyili(x)=∑i=0nyi∏j≠ix−xjxi−xj f(x)=\sum_{i=0}^{n}y_il_i(x)=\sum_{i=0}^{n}y_i\prod_{j\neq i}\frac{x-x_j}{x_i-x_j} f(x)=i=0nyili(x)=i=0nyij=ixixjxxj

也就是说若我们直接将多项式用n+1n+1n+1个点存下来,就可以做到O(n2)O(n^2)O(n2)计算带入某个xxx的值.


四.求出多项式的系数表示.

乍一看,如果要计算出这个多项式的系数表示,怎么着复杂度也是O(n3)O(n^3)O(n3)的…

其实不然,我们来转化一下:
f(x)=∑i=0nyi∏j≠ix−xjxi−xj=∑i=0nyi∏j=0n(x−xj)x−xi1∏j≠i(xi−xj) f(x)=\sum_{i=0}^{n}y_i\prod_{j\neq i}\frac{x-x_j}{x_i-x_j}\\ =\sum_{i=0}^{n}y_i\frac{\prod_{j=0}^{n}(x-x_j)}{x-x_i}\frac{1}{\prod_{j\neq i}(x_i-x_j)} f(x)=i=0nyij=ixixjxxj=i=0nyixxij=0n(xxj)j=i(xixj)1

ti=yi∏j≠i(xi−xj)t_i=\frac{y_i}{\prod_{j\neq i}(x_i-x_j)}ti=j=i(xixj)yi,容易发现tit_iti可以暴力计算,那么剩下的式子就是:
f(x)=∑i=0nti∏j=0n(x−xj)x−xi f(x)=\sum_{i=0}^{n}t_i\frac{\prod_{j=0}^{n}(x-x_j)}{x-x_i} f(x)=i=0ntixxij=0n(xxj)

g(x)=∏i=0n(x−xi)g(x)=\prod_{i=0}^{n}(x-x_i)g(x)=i=0n(xxi),容易发现g(x)g(x)g(x)也可以暴力算,式子变为:
f(x)=∑i=0ntig(x)x−xi f(x)=\sum_{i=0}^{n}t_i\frac{g(x)}{x-x_i} f(x)=i=0ntixxig(x)

接下来的问题就是O(n)O(n)O(n)计算g(x)x−xi\frac{g(x)}{x-x_i}xxig(x),这可以用背包方案数的技巧做到.

时间复杂度O(n2)O(n^2)O(n2).


五.利用拉格朗日插值法计算自然数幂和.

首先我们需要推一下自然数幂和的式子.记:
Sk(n)=∑i=1nik S_{k}(n)=\sum_{i=1}^{n}i^{k} Sk(n)=i=1nik

那么有:
Sk(n)=Sk(n+1)−(n+1)k=∑i=1n(i+1)k−(n+1)k+1=∑i=1n∑j=0k(kj)ij−(n+1)k+1=∑i=0k(ki)∑j=1nji−(n+1)k+1=∑i=0k(ki)Si(n)−(n+1)k+1 S_k(n)=S_k(n+1)-(n+1)^{k}\\ =\sum_{i=1}^{n}(i+1)^{k}-(n+1)^{k}+1\\ =\sum_{i=1}^{n}\sum_{j=0}^{k}\binom{k}{j}i^{j}-(n+1)^{k}+1\\ =\sum_{i=0}^{k}\binom{k}{i}\sum_{j=1}^{n}j^{i}-(n+1)^{k}+1\\ =\sum_{i=0}^{k}\binom{k}{i}S_{i}(n)-(n+1)^{k}+1 Sk(n)=Sk(n+1)(n+1)k=i=1n(i+1)k(n+1)k+1=i=1nj=0k(jk)ij(n+1)k+1=i=0k(ik)j=1nji(n+1)k+1=i=0k(ik)Si(n)(n+1)k+1

推到这一步,我们来尝试一下推出Sk−1(n)S_{k-1}(n)Sk1(n)
Sk−1(n)=1k((n+1)k−1−∑i=0k−2(ki)Si(n)) S_{k-1}(n)=\frac{1}{k}\left((n+1)^{k}-1-\sum_{i=0}^{k-2}\binom{k}{i}S_i(n)\right) Sk1(n)=k1((n+1)k1i=0k2(ik)Si(n))

也就是:
Sk(n)=1k+1((n+1)k+1−1−∑i=0k−1(k+1i)Si(n)) S_{k}(n)=\frac{1}{k+1}\left((n+1)^{k+1}-1-\sum_{i=0}^{k-1}\binom{k+1}{i}S_{i}(n)\right) Sk(n)=k+11((n+1)k+11i=0k1(ik+1)Si(n))

经过一波操作之后,我们确定了自然数幂和的式子,但是直接计算是O(k2)O(k^2)O(k2)的,并不够优秀.

经过观察之后,我们发现这个式子必然是关于nnnk+1k+1k+1次多项式,那么接下来就是计算点和拉格朗日插值了.

计算点非常容易,对于所有i∈[0,k+1]i\in [0,k+1]i[0,k+1],只需要计算出iki^{k}ik然后前缀和一下就是Sk(i)S_k(i)Sk(i)了,这一部分的时间复杂度为O(klog⁡k)O(k\log k)O(klogk).

然后是拉格朗日插值,然而是O(k2)O(k^2)O(k2)的,复杂度并没有变…

但是这不是大问题,我们观察所取的点,发现是连续的k+2k+2k+2个点,这会有什么用呢?

代入拉格朗日插值公式:
f(n)=∑i=0k+1Sk(i)∏j≠in−ji−j=∑i=0k+1Sk(i)1i!(−1)k+1−i(k+1−i)!∏j≠i(n−j) f(n)=\sum_{i=0}^{k+1}S_k(i)\prod_{j\neq i}\frac{n-j}{i-j}\\ =\sum_{i=0}^{k+1}S_k(i)\frac{1}{i!(-1)^{k+1-i}(k+1-i)!}\prod_{j\neq i}(n-j) f(n)=i=0k+1Sk(i)j=iijnj=i=0k+1Sk(i)i!(1)k+1i(k+1i)!1j=i(nj)

对于最后一个连乘式,我们令:
P(i)=∏j=0i(n−j)S(i)=∏j=ik+1(n−j) P(i)=\prod_{j=0}^{i}(n-j)\\ S(i)=\prod_{j=i}^{k+1}(n-j) P(i)=j=0i(nj)S(i)=j=ik+1(nj)

那么有:
f(n)=∑i=0k+1Sk(i)P(i−1)∗S(i+1)i!(−1)k+1−i(k+1−i)! f(n)=\sum_{i=0}^{k+1}S_k(i)\frac{P(i-1)*S(i+1)}{i!(-1)^{k+1-i}(k+1-i)!} f(n)=i=0k+1Sk(i)i!(1)k+1i(k+1i)!P(i1)S(i+1)

这就可以做到O(k)O(k)O(k)拉格朗日插值了.

总时间复杂度即为O(klog⁡k)O(k\log k)O(klogk).通过一个线性筛iki^{k}ik的操作,可以做到O(k)O(k)O(k).

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值