NTT 数论变换

在 FFT 中,需要用到复数和 double,这有两个问题:精度较低和无法实现取模。

所幸,这两个问题都可以用一个东西解决:NTT。

NTT 所解决的问题和 FFT 相似:

有两个多项式 f(x)=a0+a1x1+a2x2++akxkf(x) = a_0 + a_1x^1 + a_2x^2 + \cdots + a_kx^kg(x)=b0+b1x1+b2x2++blxlg(x) = b_0 + b_1x^1 + b_2x^2 + \cdots + b_lx^l

h(x)=f(x)g(x)h(x) = f(x) \cdot g(x) ,但 h(x)h(x) 每项系数对 PP 取模。

我们考虑用一个叫做原根的东西代替单位根,设 nn 次单位根为 ωn\omega_n

四条性质

在 FFT 中所用到了四条单位根的性质,它们是:

  1. 对于 0i<n0 \le i \lt nωni\omega_n^i 各不相同。

  2. 折半定理 ωni\omega_n^i = ω2n2i\omega_{2n}^{2i} ,用于分治。

  3. ωni\omega_n^i = -ωni+n2\omega_n^{i + \frac n 2} ,用于分治。

  4. 对于 t=i=0n1ωnkit = \sum_{i=0}^{n-1} \omega_n^{ki} , 当 k=0k = 0 时, t=nt = n ,否则 t=0t = 0 ,用于 IDFT 。

对于质数 P=2tq+1P = 2^t q + 1 ,其的原根 gg 为满足 gi,0i<Pg^i, 0 \le i \lt P 互不相同的数。

考虑这四个性质,令 n=2tn = 2^tωn=gq\omega_n = g^q

  1. 显然 00,q,2q,,(n1)q<P0 \le 0, q, 2q, \cdots , (n-1)q \lt P ,故 ω0,ω1,ω2,,ωn1<P\omega^0, \omega^1, \omega^2, \cdots, \omega^{n-1} \lt P 互不相同,满足。

  2. ω2n2i=(gn2)2i=gni=ωni\omega_{2n}^{2i} = (g^{\frac n 2})^{2i} = g^{ni} = \omega_n^i

  3. 根据费马小定理 ωn=gP1=1 (mod P)\omega^n = g^{P-1} = 1\ (\bmod\ P),又因为 (ωn2)2=ωn=1(\omega^{\frac n 2})^2 = \omega^n = 1 ,所以 ωn2=1 or 1\omega^{\frac n 2} = 1 \text{ or } -1 ,又因为 gig^i 互不相同,所以 ωn2=1\omega^{\frac n 2} = -1 ,所以 ωni=ωni+n2\omega_n^i = -\omega_n^{i + \frac n 2}

  4. k0k \not= 0

S(k)=(ωk)0+(ωk)1++(ωk)(n1)ωkS(k)=(ωk)1+(ωk)2++(ωk)nωkS(k)S(k)=(ωk)n1S(k)=ωnk1ωk1\begin{aligned} S(k) &= (\omega^k)^0 + (\omega^k)^1 + \cdots + (\omega^k)^{(n-1)} \\ \omega^k S(k) &= (\omega^k)^1 + (\omega^k)^2 + \cdots + (\omega^k)^n \\ \omega^k S(k) - S(k) &= (\omega^k)^n - 1 \\ S(k) &= \frac {\omega^{nk} - 1} {\omega^k - 1} \end{aligned}

由于 ωnmodP=1\omega_n \bmod P = 1 ,所以 ωnk1modP=0\omega^{nk} - 1 \bmod P = 0 ,所以 S(k)=0S(k) = 0

求原根

先略过,记住几个常用的模数的原根。

PP 分解 gg
998244353998244353 7×17×223+17 \times 17 \times 2^{23} + 1 33
10045358091004535809 479×221+1479 \times 2^{21} + 1 33

参考资料

oi-wiki.org

「Menci」大大的博客