给定一个 n 次多项式 A 和一个 m 次多项式 B,计算 A×B,系数对 p 取模。
n,m≤105
做法
设
A0i=⌊MAi⌋,A1i=AimodMB0i=⌊MBi⌋,B1i=BimodM
于是
A=M⋅A0+A1B=M⋅B0+B1
进一步
A×B=M2⋅A0⋅B0+M(A0⋅B1+A1⋅B0)+A1⋅B1
先对 A0,A1,B0,B1 做一遍 DFT,求出 A0×B0,A0×B1+A1×B0,A1×B1 的点值表示后再分别 IDFT,共 7 次。
注意系数可能达到 1014,需要用 wnk=cosn2kπ+i⋅sinn2kπ 对 wnk 进行预处理保证精度。
优化
下面考虑这样两件事:
-
现在要对实系数多项式 A,B 进行 DFT。
我们定义
P=A+iBQ=A−iB
推导可以得到一个很优美的结论:
conj(Q(wnk))=P(conj(wnk))
于是只需一次 DFT 就可以求出 A,B 的点值表示。
-
现在已知实系数多项式 A,B 的点值表示 A′,B′,要求 A,B。
我们定义
P=A′+iB′
对 P 进行 IDFT 得到 P′,于是
P′=A+iB
因此 P′ 的实数部分就是 A, 虚数部分就是 B。
于是只需一次 IDFT 就可以达到对 A′,B′ 分别做 IDFT 的效果.
将 7 次 DFT 两两配对可以合并成 4 次 DFT。
代码
参考资料
国家集训队 2016 论文集,《再探快速傅里叶变换》毛啸。