前言
最近在做历年的NOI原题,然后就做到了[NOI2019] 机器人,惊讶地发现我居然没学过拉格朗日插值🤡!
之前的省选题本来有一道拉插的题([省选联考 2022] 填树),但是在
简介
粘的别人的
在数值分析中,拉格朗日插值法是以法国18世纪数学家约瑟夫·拉格朗日命名的一种多项式插值方法。如果对实践中的某个物理量进行观测,在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。上面这样的多项式就称为拉格朗日(插值)多项式。
拉格朗日插值法
众所周知,给出一个 次多项式的 个点值可以唯一地求出这个多项式,一个朴素的求法就是列出 个方程然后使用高斯消元,复杂度 ,往往还伴随精度问题。
而拉格朗日插值法可以在
直接上拉格朗日插值公式:
这个式子十分巧妙,因为带入后可以发现它刚好能取到所有的点值,并且次数最大为 。
用这个公式直接求多项式虽然也是 (还比高消慢),但是是可以优化滴!
我们可以先求出 ,然后枚举 时先 计算下面的 ,然后由于 在计算的时候没有被掐断,所以单个 可以整除 ,直接 递推求出 即可(注意特判 )。这样总的复杂度就降为了 。
求单个点值
这里求单个点值的意思是给出 ,我们需要求 。
我们显然可以直接求出 然后带入求解,但是当我们的目的仅仅是求出
我们不妨直接带入拉格朗日插值公式:
由于不再是求多项式,所以我们可以在 时间内求出所有的 ,然后每次枚举 时就只用求 了。虽然还是 ,但是减小了常数且更简单。
O(n)求单个点值
还是只要求求出 。
在多数应用到拉插的题目中,这 个点值是满足下标连续,或者等间距的,即 。
此时我们可以做些预处理(比如当间距等于 1 的时候,你需要预处理阶乘的逆元),然后就可以单次 求出 。(需要特别注意符号问题)
应用
有一个经典问题:计算 。这个问题显然可以用斯特林反演
众所周知这个东西是一个关于 的 次多项式,所以我们可以先 (忽略快速幂,你也可以用线性筛)求出前 个点值,然后用上面的方法 拉插求出 处的答案,这样总复杂度只有 。
更实用的场景是在一些DP题中,比如你需要求 个DP值来转移,但是你发现这 个点值的函数是一个次数较小的 次多项式,那么就可以只求前
一般要看出这是个多项式需要归纳证明,但是我不会
进阶:快速插值
回到最初的问题上,我们需要求出多项式 。如果
我们需要把
稍微变一下式子:
但是这个时候式子就变得很奇怪:
然而,正因为上下两边都是0,我们可以使用洛必达法则:
所以第一步,我们可以先分治NTT求出 、,然后多项式多点求值求出每一个 。
剩下还有 这部分,再用一次分治NTT即可。
于是我们可以在