一、
给定多项式:
A(x)=i=0∑n−1aixi
目标:快速计算:
A(x0),A(x1),…,A(xn−1)
暴力复杂度:
O(n2)
FFT 目标:
O(nlogn)
二、单位根)
1. n 次单位根定义
ωn=e2πi/n
性质:
ωnn=1
2 基本引理
折半引理
ω2n2k=ωnk
消去引理
ωnk+n/2=−ωnk
三、多项式拆分
将 A(x) 按奇偶拆分:
A(x)=a0+a1x+⋯+an−1xn−1=(a0+a2x2+…)+(a1x+a3x3+…)=Ae(x2)+xAo(x2)
其中:
Ae(x)Ao(x)=a0+a2x+…=a1+a3x+…
四、DFT 递归
在单位根处求值:
yk=A(ωnk)
代入奇偶分解:
A(ωnk)=Ae(ωn2k)+ωnkAo(ωn2k)
由折半引理:
ωn2k=ωn/2k
于是:
A(ωnk)=Ae(ωn/2k)+ωnkAo(ωn/2k)
同理:
A(ωnk+n/2)=Ae(ωn/2k)−ωnkAo(ωn/2k)
一对结果,只用算一半
五、递归 FFT 伪代码
fft(a):
n=size(a)
if n==1:return a
ae=a[0,2,...]
ao=a[1,3,...]
ye=fft(ae)
yo=fft(ao)
for k=0→n/2-1:
w=pow(w_n,k)
y[k]=ye[k]+w*yo[k]
y[k+n/2]=ye[k]-w*yo[k]
return y
复杂度:
T(n)=2T(n/2)+O(n)⇒O(nlogn)
六、蝴蝶操作
核心计算单元:
{u=yev=ωnkyo⇒{yk=u+vyk+n/2=u−v
这就是蝴蝶结构的来源。
七、迭代 FFT
1. 递归的问题
2. 迭代思想
3. 位逆序置换(Rader)
索引二进制反转后排序:
000↔000
001↔100
010↔010
011↔110
目的:让递归叶子顺序对齐~
八、迭代 FFT の流程
bitReverse(a)
for len=2→n step*=2:
wlen=pow(w_n, n/len)
for i=0→n step+=len:
w=1
for k=i→i+len/2:
u=a[k]
v=w*a[k+len/2]
a[k]=u+v
a[k+len/2]=u-v
w*=wlen
九、逆 FFT(IFFT)
DFT 矩阵:
Fjk=ωnjk
逆变换:
F−1=n1F
实现方法:
把 ω_n 换成 ω_n^{-1}
最后整体除以 n
十、卷积
多项式乘法:
c=a∗b
步骤:
FFT(a)→AFFT(b)→BCk=AkBkIFFT(C)→c
复杂度:
O(nlogn)
十一、边界条件
| 项目 |
要求 |
| n |
2 的幂 |
| 模运算 |
NTT |
| 精度 |
double / long double |
| 长度 |
≥ deg(a)+deg(b)+1 |
十二、速记公式卡片
ωn=e2πi/nω2n2k=ωnkA(ωnk)=Ae(ωn/2k)+ωnkAo(ωn/2k)蝴蝶:yk=u+v, yk+n/2=u−vIFFT:ωn→ωn−1, /n
本人除了爱写一些暴力算法就没啥好些的
有帮助,赞一个