kraskevich 基本上做到了。缺少一些细节,并且太长而无法放入评论字段。以下是详细信息。
基本上,您希望设置为多项式乘法问题。您的输入将是 p1,...pN 其中 pj(x) = (x-rj)。
这是伪代码:
function multiply2Poly(p1, p2)
// here, use FFT, multiply and use IFFT back
function multiplyPoly(p[1],...p[N])
if (N==1) return p[1]
if (N==2) return multiply2Poly(p[1],p[2])
else {
return multiply2Poly(multiplyPoly(p[1],...p[N/2]),multiplyPoly(p[1+N/2],...,p[N])
}
function getCoef(r[1],...r[N])
return multiplyPoly((p[1]=x-r[1]),...(p[N]=x-r[N]));
对于 FFT 部分:
观察如果两个多项式是:
p1 = a[0]+a[1] x + ...+a[n] x^n
p2 = b[0]+a[1] x + ...+a[n] x^n
那么 p1 * p2 = c[0] + c[1] x + ...+c[n] x^n
其中 C = A [x] B 其中 [x] = 卷积。 A = (a[0],...,a[n]), B = (b[0],...,b[n]) 和 C = (c[0],...,c[ n])。
然后使用 FFT 和卷积定理来加快速度。
C = A [x] B = IFFT{ FFT{A} * FFT{B} } 其中 * 这里只是乘法。
IFFT 的运行时间 = FFT 的运行时间 = O(n log n)。
乘法运行时间为 n,因此总运行时间为 O(n log n)。
那么,multiplyPoly 的总运行时间为:
T(N) = R(N/2) + T(N/2)*2
而 R(N/2) = O(n log n) 就是上面所说的 multiply2Poly 的运行时间。
所以
T(N) = T(N/2) * 2 + O(n log n)
现在 Master 定理给出 O(n (log n)^2)