查看题目
一道大数相乘的题,大数也可以看成是多项式,再运用FFT来处理。
粗略步骤:
1. 将多项式从系数表示转为点值表示
2. 把两个多项式的点值表示相乘
3. 将相乘后的点值表示转为系数表示
1. 将多项式从系数表示转为点值表示
系数表示: A(x)=a0+a1x+a2x2+⋅⋅⋅+an−1xn−1 A ( x ) = a 0 + a 1 x + a 2 x 2 + · · · + a n − 1 x n − 1
点值表示: (x0,A(x0))、(x1,A(x1)、⋅⋅⋅) ( x 0 , A ( x 0 ) ) 、 ( x 1 , A ( x 1 ) 、 · · · ) 数个这样的点值对
这里我们巧妙地选择点值表示中的x值:
选择1的n次单位根
1的n次单位根: ωn=1 ω n = 1 ,共有n个不同的根
即 ωkn=cos(2πk/n)+i∗sin(2πk/n) ω n k = c o s ( 2 π k / n ) + i ∗ s i n ( 2 π k / n )
其中 i2=−1 i 2 = − 1
那么 A(ω)=a0+a1ω+a2ω2+⋅⋅⋅+an−1ωn−1 A ( ω ) = a 0 + a 1 ω + a 2 ω 2 + · · · + a n − 1 ω n − 1
系数向量 a⃗ =(a0,a1,⋅⋅⋅,an−1) a → = ( a 0 , a 1 , · · · , a n − 1 )
值向量 A⃗ =(A(ω0n),A(ω1n),⋅⋅⋅,A(ωn−1n)) A → = ( A ( ω n 0 ) , A ( ω n 1 ) , · · · , A ( ω n n − 1 ) )
即 A⃗ =DFT(a⃗ ) A → = D F T ( a → )
这里我们称为离散傅里叶变换
A1 = dft(a1)
A2 = dft(a2)
2. 把两个多项式的点值表示相乘
for i in range(n):
A[i] = A1[i]*A2[i]
3. 将相乘后的点值表示转为系数表示
离散傅里叶变换可写为矩阵形式 W∗a⃗ =A⃗ W ∗ a → = A →
即
⎡⎣⎢⎢⎢⎢1111