有关多项式的一个基础算法,理解起来比较困难。
快速傅里叶变换(Fast Fourier Transform,FFT)和傅里叶变换(Fourier Transform,FT)没什么关系,也不是傅里叶发明的。这种算法用于在 O(nlogn) 时间复杂度内求出两个多项式的卷积(相当于多项式之间相乘)。
前置知识
多项式的表示
n 项式等价于 n−1 次项式。(每个次项的系数都不为零)
系数表示法
形如 F(x)=n−1∑i=0aixi,把一个 n−1 次项式的每一次项都表示出来。
两个多项式直接相乘时间复杂度为 O(n2)。
点值表示法
对于一个 n−1 次多项式,可以用 n 个点 (xi,yi=F(xi) 来表示,相当于由 n 条 n 次方程组成的方程组 。
当两个表示不同多项式的点 x 坐标相等,y 坐标直接相乘。这种情况下相乘时间复杂度为 O(n)。
两种表示法间的转换
系数表示法 → 点值表示法
对于 n−1 次项式选取 n 个点计算对应值来表示。
点值表示法 → 系数表示法
根据每个点列出 n−1 元方程,通过高斯消元解出方程。
注意在上述及下文的关于多个多项式的计算中,要统一次数,次数低的多项式要在高次上补零。
复数
复数及三角函数学习笔记
单位根是在FFT的思想中一项非常重要的部分。
思想
正常多项式的的乘法并没有什么捷径,时间复杂度 O(n2)。于是数学家们想到了可以变为使用点值表示法来运算,能将相乘的时间复杂度优化到 O(n)。
接下来的难点便是如何进行系数表示法与点值表示法之间的转换。这需要用到离散傅里叶变换(Discrete Fourier Transform,DFT)和离散傅里叶逆变换(Inverse Discrete Fourier Transform,IDFT)。
请注意接下来的内容中 n=2m,其中 m∈N(m 是正整数),许多性质需要依靠这个条件才能推出来。
DFT
DFT 是一种将多项式从系数表示法转换为点值表示法的算法。
我们设多项式 A(x)=a0+a1x+a2x2+a3x3+⋯+an−1xn−1。
将其系数及其所对应项按照下标奇偶性分类,则有
A(x)=(a+a2x2+a4x4+⋯+an−2xn−2)+(a1x1+a3x3+⋯+an−1xn−1)
设
A1(x)=a0+a2x+a4x2+⋯+an−2xn2−1A2(x)=a1x+a3x2+a5x3+⋯+an−1xn2−1
(注意此处 x 指数的区别以及此处的 n 与上个公式是同一个)
可以得到:
A(x)=A1(x2)+xA2(x2)
此时将 x=ωkn(0<k<n2) 带入 A(x),得
A(ωkn)=A1(ω2kn)+ωknA2(ω2kn)
同理,将 x=ωk+n2n(0<k<n2) 带入 A(x),得
A(ωk+n2n)=A1(ω2k+nn)+ωk+n2nA2(ω2k+nn)=A1(ω2kn⋅ωnn)+ωk+n2nA2(ω2kn⋅ωnn)=A1(ω2kn⋅1)+ωkn⋅ωn2n⋅A2(ω2kn⋅1)=A1(ω2kn)−ωknA2(ω2kn)
我们发现这个公式与上面那个公式很像,只有一个系数不一样。也就是说,如果我们知道上面那个
公式,那么下面那个公式就能在 O(1) 的时间内求出来。
发现当 k 的的取值遍历 [0,n2−1] 时,k+n2 的取值正好遍历了 [n2,n−1]。
也就是说,只需要算出多项式的一半,另一半就能立马算出来,变成了类似于分治的一种思想。
这种思想的时间复杂度为 O(nlogn)。
IDFT
IDFT 是一种将多项式从点值表示法转换为系数表示法的算法。是 DFT 的逆算法。