Fast Fourier Transform

多项式的点值表示法

Fact

nn 个点可以唯一表示 degree 为 n1n-1 的多项式 f(x)=a0+a1x+a2x2++an1xn1f(x)=a_0+a_1x+a_2x^2+\dots +a_{n-1}x^{n-1}.

所以,两个度数为 n1n-1 的多项式 f(x),g(x)f(x),g(x),其乘积 h(x)h(x)2n22n-2 度的多项式 h(x)=i=02n2bixih(x)=\sum_{i=0}^{2n-2} b_ix^i

h(x)h(x) 的点值表示法需要 2n12n-1 个点,那么为了从 f(x),g(x)f(x),g(x) 计算出 h(x)h(x),我们也需要在 f(x),g(x)f(x),g(x) 上取 2n12n-1 个点。

而朴素的多项式乘法需要 O(n2)O(n^2),所以,只要我们可以用比 O(n2)O(n^2) 的方式计算出 f(x),g(x)f(x),g(x) 上的 2n12n-1 个点 (xi,f(xi)),(xi,g(xi))(x_i,f(x_i)),(x_i,g(x_i)),然后再以 O(n)O(n) 把点乘起来 (xi,f(xi)g(xi))(x_i,f(x_i)\cdot g(x_i)) 得到 (xi,h(xi))(x_i,h(x_i)),再将 h(x)h(x) 上的 2n12n-1 个点转化成系数表示法,就大功告成了!

所以我们的思路是

Coefficient RepresentationFFT InverseFFT ForwardPoint-Value Representation \boxed{\text{Coefficient Representation}}\overset{\text{FFT Forward}}{\underset{\text{FFT Inverse}}{\rightleftarrows}} \boxed{\text{Point-Value Representation}}

用线性对数时间复杂度计算 Point-Value Representation

怎么以 O(nlogn)O(n\log n) 计算 f(x)f(x)2n12n-1 个点值呢?考虑分治,令 f(x)f(x) 的 Coefficient Representation 为

f(x)=a0+a1x+a2x2+a3x3+an1xn1 f(x)=a_0+a_1x+a_2x^2+a_3x^3+\dots a_{n-1}x^{n-1}

f(x)f(x) 的系数分成偶数项和奇数项:

(a0,a2,,an2)    f0(x)=a0+a2x+a4x2++an2xn21(a1,a3,,an1)    f1(x)=a1+a3x+a5x2++an1xn21 (a_0,a_2,\dots,a_{n-2})\implies f_0(x)=a_0+a_2x+a_4x^2+\dots +a_{n-2}x^{\frac{n}{2}-1}\\ (a_1,a_3,\dots,a_{n-1})\implies f_1(x)=a_1+a_3x+a_5x^2+\dots +a_{n-1}x^{\frac{n}{2}-1}

所以我们有

f(x)=f0(x2)+xf1(x2) f(x) = f_0(x^2) + x\cdot f_1(x^2)

考虑两个点 x1,x2x_1,x_2,如果我们不用任何优化,我们一共需要计算 44 个值,才能计算出两个点值:f0(x12),f1(x12),f0(x22),f1(x22)f_0(x_1^2),f_1(x_1^2),f_0(x_2^2),f_1(x_2^2).

然而,如果我们令 x1=x2x_1=-x_2,也就是说 x12=x22x_1^2=x_2^2,那么我们只需要计算 22 个值,就可以计算出两个点值了:f0(x12),f1(x12)f_0(x_1^2),f_1(x_1^2).

所以,令 T(n)T(n) 表示计算 degree 为 nnf(x)f(x) 的点值,则

T(n)=2T(n/2)+O(n)T(n)=O(nlogn) T(n)=2T(n/2)+O(n)\\ T(n)=O(n\log n)

引入复数

上一节我们已经知道了,考虑 nn 个值 x0,x1,x2,xn1x_0,x_1,x_2\dots, x_{n-1} 需要满足

x0=xn/2x1=xn/2+1xn/21=xn1 x_0=-x_{n/2}\\ x_1=-x_{n/2+1}\\ \dots\\ x_{n/2-1}=-x_{n-1}

然后进入递归,我们就需要对 n/2n/2 个值 x02,x12,x22xn/212x_0^2,x_1^2,x_2^2\dots x_{n/2-1}^2 对应的点值 f(x02),f(x12),f(x22),f(xn/212)f(x_0^2),f(x_1^2),f(x_2^2)\dots ,f(x_{n/2-1}^2)

类似的,为了进一步递归下去,这 n/2n/2 个值也应该满足

x02=xn/42x12=xn/4+12xn/412=xn/212 x_0^2=-x_{n/4}^2\\ x_1^2=-x_{n/4+1}^2\\ \dots\\ x_{n/4-1}^2=-x_{n/2-1}^2\\

这里就必须引入复数了(不然只能全部等于 00)。