的形式。
对于两个多项式
A(x) A ( x )
和
B(x) B ( x )
,我们可以计算乘积
A⋅B A ⋅ B
:
A⋅B=∑i=0sizeA∑j=0sizeBaibjxi+j A ⋅ B = ∑ i = 0 s i z e A ∑ j = 0 s i z e B a i b j x i + j
但是,这样算是
O(sizeA⋅sizeB) O ( s i z e A ⋅ s i z e B )
的,太慢了,怎么办?
我们需要换一条思路。
首先,我们得知道一个东西:多项式的点值表示法。 我们把上面的称为多项式的系数表示法,而点值表示法就是: 若A A 多项式的次数为n,则任取n n 个不相同的x0,x1,⋯,xn,求出A A 多项式的A(x0),A(x1),⋯,A(xn)。记为:
<(x0,A(x0)),(x1,A(x1)),⋯,(xn,A(xn))> < ( x 0 , A ( x 0 ) ) , ( x 1 , A ( x 1 ) ) , ⋯ , ( x n , A ( x n ) ) >
<script type="math/tex; mode=display" id="MathJax-Element-15"><(x_0,A(x_0)),(x_1,A(x_1)),\cdots,(x_n,A(x_n))></script>显然,一个有
n+1 n + 1
个点的点对唯一表示一个
n n
次多项式。
对于一个点值表示法下多项式
<(x0,A(x0)),(x1,A(x1)),⋯,(xn,A(xn))>
和
<(x0,B(x0)),(x1,B(x1)),⋯,(xn,B(xn))> < ( x 0 , B ( x 0 ) ) , ( x 1 , B ( x 1 ) ) , ⋯ , ( x n , B ( x n ) ) >
<(x0,A(x0)⋅B(x0)),(x1,A(x1)⋅B(x1)),⋯,(xn,A(xn)⋅B(xn))> < ( x 0 , A ( x 0 ) ⋅ B ( x 0 ) ) , ( x 1 , A ( x 1 ) ⋅ B ( x 1 ) ) , ⋯ , ( x n , A ( x n ) ⋅ B ( x n ) ) >
<script type="math/tex; mode=display" id="MathJax-Element-20"><(x_0,A(x_0)\cdot B(x_0)),(x_1,A(x_1)\cdot B(x_1)),\cdots,(x_n,A(x_n)\cdot B(x_n))></script>可以看出点值表示法的多项式相乘是
O(n) O ( n )
的。
等等,我们好像找到了一个突破口! 为啥不把原来的系数表示法下的多项式转化成点值表示法呢? 仔细想一想:系数表示法与点值表示法互相转换,这个步骤好像是O(n2) O ( n 2 ) 的。 而FFT(快速傅里叶变换)就是为了优化这个O(n2) O ( n 2 ) 。
PS:对于O(n2) O ( n 2 ) 的点值表示法转化成系数表示法可以看百度百科中关于插值法的介绍。
FFT(快速傅里叶变换)
如果未特别说明,那么下面的多项式次数将是2k−1 2 k − 1 的形式。 如果不是关键部分的公式或定理,不提供证明,自己出门右转百度。