FFT小记
用途
计算多项式乘法,即加法卷积
暴力计算是\(O(N^2)\)的,考虑先把多项式从系数表达转成点值表达,然后点值直接相乘,再把点值转化成系数表达
DFT(离散傅里叶变换)
DFT将系数表达转化成点值表达,暴力求n个点的点值表达是\(O(N^2)\)的,但是用分治+单位根可以做到\(O(Nlog N)\)
考虑一个有n-1次多项式,共有n项,这里考虑的n都为2的整幂。
\(F(x)=\sum_{i=0}^{n-1}F[i]x^i\)
把它的奇数项和偶数项分开,
\(F(x)=(\sum_{i=0}^{\frac{n}{2}-1}F[2i]x^{2i})+(\sum_{i=0}^{\frac{n}{2}-1}F[2i+1]x^{2i+1})\)
形成两个\(\frac{n}{2}\)项的多项式:
\(FL(x)=\sum_{i=0}^{\frac{n}{2}-1}F[2i]x^{i}\)
\(FR(x)=\sum_{i=0}^{\frac{n}{2}-1}F[2i+1]x^{i}\)
那么有
\(F(x)=FL(x^2)+xFR(x^2)\)
于是求\(F(x)\)的点值表达可以分治为求\(FL(x)\)和\(FR(x)\)的点值表达
如果随便找一些数带进去的话,每次分治两边都要求n个点的点值,点的数量并没有减少,这样分治下去,复杂度\(O(N^2log N)\),还不如暴力呢
但是利用单位根的一些性质,可以每次分治的时候可以令分治下去的两个多项式各计算\(\frac{n}{2}\)个点值,这样复杂度就降为了\(O(Nlog N)\)
假设我们要求出\(w_n^0~w_n^{n-1}\)这n个点的点值,那么代入\(w_n^k\)和\(w_n^{k+\frac{n}{2}}(0\leq k<\frac{n}{2})\)
化简可以得到:
\(F(w_n^k)=FL(w_{n/2}^k)+w_n^kFR(w_{n/2}^k)\)
\(F(w_n^{k+n/2})=FL(w_{n/2}^k)-w_n^kFR(w_{n/2}^k)\)
可以发现,原来的n个点,根据是否小于\(n/2\)代入讨论,最后分治两边各只需要求出\(n/2\)个点值。
IDFT(离散傅里叶逆变换)
通过DFT,我们可以计算出多项式的点值表达,两个多项式的点值表达相乘后得到这两个多项式乘积的点值表达,接下来考虑将点值表达转化成系数表达,即IDFT
设\(G[k]\)为\(w_n^k(k\in [0,n-1])\)处的点值,则\(G[k]=\sum_{i=0}^{n-1}(w_n^k)^iF[i]\)
通过反演可以得到,
\(n\times F[k]=\sum_{i=0}^{n-1}(-w_n^k)^iG[i]\)
也就是说,多项式的\(k\)次项系数等于把\(G\)看做一个多项式后,\(-w_n^k\)处的点值除以\(n\)

浙公网安备 33010602011771号