快速数论变换 (NTT)
之前写了一篇关于多项式算法的博客,提到了快速傅立叶变换 (FFT)。
快速傅立叶变换中使用了单位复数根来进行采样与插值,快速数论变换和这是类似的,只不过使用的是原根。
原根的性质
为了方便,假设下面所有的
其中
考虑下单位复数根为什能做到
$$ \omega_n^n = 1 \\ \omega_n^{n/2} = -1$$
对原根而言:
而:
方程
$$ \omega_{dn}^{dk} = \omega_n^k $$
原根也可以:
(折半引理)
$$ \{(\omega_n^k)^2\} = \{\omega_{n/2}^k\} $$
原根依然可以。根据上面的结论,我们有:
因此,单位复数根该有的性质原根居然都有!
NTT 算法
从上面的讨论中我们知道,将你的 FFT 代码中的单位复数根换成
逆 FFT 变换时需要除以
NTT 的总复杂度与 FFT 一致,是
最后还剩下一个问题:
在 FFT 中,为了方便处理,
为了方便,通常选定:
它的最小正原根是
另外一个是著名的 UOJ 模数
使用快速数论变换的好处就是避免了浮点数精度误差。当输入系数都是整型的时候最好优先考虑 NTT。
-
$x^2 \equiv 1 \Leftrightarrow x^2 - 1 \equiv 0 \Leftrightarrow (x + 1)(x - 1) \equiv 0 \pmod p$ ,所以$p \mid (x + 1)(x - 1)$ 。由于$p$ 是质数,所以要么$p | (x + 1)$ ,要么$p | (x - 1)$ ,分别对应$x \equiv -1$ 和$x \equiv 1$ 的情况。 ↩