多项式的点值表示法
n 个点可以唯一表示 degree 为 n−1 的多项式 f(x)=a0+a1x+a2x2+⋯+an−1xn−1.
所以,两个度数为 n−1 的多项式 f(x),g(x),其乘积 h(x) 为 2n−2 度的多项式 h(x)=∑i=02n−2bixi
h(x) 的点值表示法需要 2n−1 个点,那么为了从 f(x),g(x) 计算出 h(x),我们也需要在 f(x),g(x) 上取 2n−1 个点。
而朴素的多项式乘法需要 O(n2),所以,只要我们可以用比 O(n2) 的方式计算出 f(x),g(x) 上的 2n−1 个点 (xi,f(xi)),(xi,g(xi)),然后再以 O(n) 把点乘起来 (xi,f(xi)⋅g(xi)) 得到 (xi,h(xi)),再将 h(x) 上的 2n−1 个点转化成系数表示法,就大功告成了!
所以我们的思路是
Coefficient RepresentationFFT Inverse⇄FFT ForwardPoint-Value Representation 用线性对数时间复杂度计算 Point-Value Representation
怎么以 O(nlogn) 计算 f(x) 的 2n−1 个点值呢?考虑分治,令 f(x) 的 Coefficient Representation 为
f(x)=a0+a1x+a2x2+a3x3+…an−1xn−1把 f(x) 的系数分成偶数项和奇数项:
(a0,a2,…,an−2)⟹f0(x)=a0+a2x+a4x2+⋯+an−2x2n−1(a1,a3,…,an−1)⟹f1(x)=a1+a3x+a5x2+⋯+an−1x2n−1所以我们有
f(x)=f0(x2)+x⋅f1(x2)考虑两个点 x1,x2,如果我们不用任何优化,我们一共需要计算 4 个值,才能计算出两个点值:f0(x12),f1(x12),f0(x22),f1(x22).
然而,如果我们令 x1=−x2,也就是说 x12=x22,那么我们只需要计算 2 个值,就可以计算出两个点值了:f0(x12),f1(x12).
所以,令 T(n) 表示计算 degree 为 n 的 f(x) 的点值,则
T(n)=2T(n/2)+O(n)T(n)=O(nlogn) 引入复数
上一节我们已经知道了,考虑 n 个值 x0,x1,x2…,xn−1 需要满足
x0=−xn/2x1=−xn/2+1…xn/2−1=−xn−1然后进入递归,我们就需要对 n/2 个值 x02,x12,x22…xn/2−12 对应的点值 f(x02),f(x12),f(x22)…,f(xn/2−12)
类似的,为了进一步递归下去,这 n/2 个值也应该满足
x02=−xn/42x12=−xn/4+12…xn/4−12=−xn/2−12这里就必须引入复数了(不然只能全部等于 0)。