快速数论变换(NTT)
将快速傅里叶变换(FFT)中的单位根换成原根,就成了快速数论变换(NTT)。NTT 没有精度误差,但是 NTT 要求系数为整数,且要对特殊的质数取模(设这个质数是 $p$,且 $p=r \times 2^k+1$,$2 \not | r$,$k \in \mathbb{N}$,那么它只能用来处理乘积的最高次数 $<2^k$ 的多项式乘法)。
引入
回顾 FFT 中用到的 $\omega$ 的性质:
- $\omega_n^n=1$;
- $\omega_n^0,\omega_n^1,\omega_n^2,\cdots,\omega_n^{n-1}$ 两两不等,可以还原出系数;
- 当 $n$ 为偶数时,$\omega_n^2=\omega_{n \div 2}$,$\omega_n^{n \div 2+k}=-\omega_n^k$,按照指数奇偶分类之后能够把带入的值也减半使得问题规模能够减半;
- $\sum\limits_{k=0}^{n-1}(\omega_n^{j-i})^k=n \times [i=j]$,能够用相同的方法进行逆变换得到系数表示。
可以使用原根代替单位根来实现 FFT,简称 NTT。
根据费马小定理,对于一个素数 $p$,有如下关系:$a^{p-1} \equiv 1 \pmod p$。
概念:原根。$p$ 的原根 $g$ 定义为使得 $g^0 \bmod p,g^1 \bmod p,\cdots,g^{p-2} \bmod p$ 互不相同的数。
取素数 $p=k \times n+1$,其中 $n$ 为 $2$ 的正整数次幂,$k \in \mathbb{N}^*$,原根为 $g$,令 $g_n \equiv g^k \pmod p$,这样就可以满足 $g_n^0 \bmod p,g_n^1 \bmod p,\cdots,g_n^{n-1} \bmod p$ 互不相同,并且 $g_n^1 \equiv 1 \pmod p$,满足性质 1、2。
由于 $p$ 是素数,并且 $g_n^n \equiv 1 \pmod p$,这样 $g_n^{\frac{n}{2}}$ 必然是 $-1$ 或 $1$。再根据互不相同这个特点,$g_n^{\frac{n}{2}} \equiv -1 \pmod p$,满足性质 3。
代码实现
模板题:Luogu P3803
递归版
迭代版
封装代码
递归版
迭代版
高度封装代码
迭代版
任意模数 NTT:MTT
若题目给出的模数 $P$ 不存在原根,可以估计一下答案的范围(一般为 $n \times \max\{a_i\}^2$,在 $[0,10^{23}]$ 范围内),可以求出答案对三个大质数的模,再用中国剩余定理合并。
模板题:Luogu P4245。
普通版
高度封装版
如果要包装 mod_int,不同模数之间的运算需要处理。
原根表
此表格来自 FFT用到的各种素数 – Miskcoo's Space(现在已经不可查看),Wayback Machine。
| 模数 $p=r \times 2^k+1$ | $r$ | $k$ | 最小原根 $g$ |
|---|---|---|---|
| 3 | 1 | 1 | 2 |
| 5 | 1 | 2 | 2 |
| 17 | 1 | 4 | 3 |
| 97 | 3 | 5 | 5 |
| 193 | 3 | 6 | 5 |
| 257 | 1 | 8 | 3 |
| 7681 | 15 | 9 | 17 |
| 12289 | 3 | 12 | 11 |
| 40961 | 5 | 13 | 3 |
| 65537 | 1 | 16 | 3 |
| 786433 | 3 | 18 | 10 |
| 5767169 | 11 | 19 | 3 |
| 7340033 | 7 | 20 | 3 |
| 23068673 | 11 | 21 | 3 |
| 104857601 | 25 | 22 | 3 |
| 167772161 | 5 | 25 | 3 |
| 469762049 | 7 | 26 | 3 |
| 998244353 | 119 | 23 | 3 |
| 1004535809 | 479 | 21 | 3 |
| 2013265921 | 15 | 27 | 31 |
| 2281701377 | 17 | 27 | 3 |
| 3221225473 | 3 | 30 | 5 |
| 75161927681 | 35 | 31 | 3 |
| 77309411329 | 9 | 33 | 7 |
| 206158430209 | 3 | 36 | 22 |
| 2061584302081 | 15 | 37 | 7 |
| 2748779069441 | 5 | 39 | 3 |
| 6597069766657 | 3 | 41 | 5 |
| 39582418599937 | 9 | 42 | 5 |
| 79164837199873 | 9 | 43 | 5 |
| 263882790666241 | 15 | 44 | 7 |
| 1231453023109121 | 35 | 45 | 3 |
| 1337006139375617 | 19 | 46 | 3 |
| 3799912185593857 | 27 | 47 | 5 |
| 4222124650659841 | 15 | 48 | 19 |
| 7881299347898369 | 7 | 50 | 6 |
| 31525197391593473 | 7 | 52 | 3 |
| 180143985094819841 | 5 | 55 | 6 |
| 1945555039024054273 | 27 | 56 | 5 |
| 4179340454199820289 | 29 | 57 | 3 |
例题
| 名称 | 编号 | 备注 | 题解 |
|---|---|---|---|
| 给定 $n$ 个长度分别为 $a_i$ 的木棒,问随机选择 $3$ 个木棒能够拼成三角形的概率 | |||
| Triple | BZOJ 3771 | 提交记录 备份 | |
| 快速数论变换(NTT),Chirp Z 变换 | |||