Fourier变换应用小记
大整数问题一直很头疼,采用乘法原理的结果复杂度为$O(n^{2})$,最近看傅里叶变换有尝试用傅里叶变换加以改进。
设
$$ a=(a_{N-1}a_{N-2}…a_{1}a_{0}){10}=a{N-1}10^{N-1}+…+a_{0}10^{0}] [b=(b_{N-1}b_{N-2}…b_{1}b_{0}){10}=b{N-1}10^{N-1}+…+b_{0}10^{0} $$
两个式子的乘积
$$ c = ab = c_{2N-2}10^{2N-2}+c_{2N-3}10^{2N-3}+…+c_{1}10^{1}+c_{0}10^{0} $$
其中
$$ c_{k}=\sum_{i+j=k}a_{i}b_{j},(i=0,…,N-1) $$
这种算法的时间复杂度为$O(n^{2})$。
逆天的是,${c_{k}}$居然逆天的等于${a_{k}}$和${b_{k}}$点的卷积。我们知道,卷积可以通过傅里叶变换的方式转化为普通乘法(函数卷积的傅里叶变换是函数傅里叶变换的乘积)。 于是,我们有: (1)求${a_{i}}$和${b_{j}}$的傅里叶变换(离散)${A_{i}}$和${B_{j}}$ (2)${A_{i}}$和${B_{j}}$逐项相乘得到${C_{k}}$ (3)对${C_{k}}$求傅里叶逆变换,得到${c_{k}}$ (4)进位,出结果
对复向量${x_{N-1},…,x_{1},x_{0}}$,离散傅里叶变换为:
$$ X_{k}=\sum_{n=0}^{N-1}x_{n}e^{\frac{-2i\pi nk}{N}},(k=0,…,N-1) $$
逆变换公式为:
$$ x_{k}=\frac{1}{N}\sum_{k=0}^{N-1}X_{k}e^{\frac{-2i\pi kn}{N}},(n=0,…,N-1) $$
例: 三位数($N=3$)$a=456,b=987$,求c=ab。 结果为:c=450072。共 6 位数字,$N$扩展到$2^3 = 8$。
$$ { a_7, a_6, a_5, a_4, a_3, a_2, a_1, a_0 } = { 0, 0, 0, 0, 0, 4, 5, 6 } $$
$$ { b_7, b_6, b_5, b_4, b_3, b_2, b_1, b_0 } = { 0, 0, 0, 0, 0, 9, 8, 7 } $$