快速数论变换-NTT

前文再续,书接上一回,我们说到多项式乘法可以用 FFT 来处理,但由于多次使用三角函数以及复数,难免带来精度的问题,动不动就炸掉了

于是,快速数论变换(NTT)就横空出世

他是一种用原根代替单位根的算法,他不仅保证了精度(在整数域内),而且支持多项式的取模,因此是一种优秀的算法


1. 原根

首先我们要了解原根是啥:

  • 阶:形如 \(x^k\equiv 1\ (mod\ p)\) 的最小正整数 \(k\) 称为 \(x\) 的阶

  • 原根:若 \(1\le g<n\),满足阶为 \(\phi(p)\) 的数 \(g\) 称为 \(p\) 的原根

说白了,就是 \(k\) 取不同值时,\(g^k\) 在模 \(p\) 意义下的取值都不同

模板题(求原根)

注:以下定理均无证明,需要的请自行查阅

首先,只有如下这几类数才有原根:\(2,4,p^k,2p^k\)\(p\) 为奇质数

我们考虑找到 \(p\)最小原根 \(g\) :已有证明显示,\(g\)\(n^{0.25}\) 级别的,因此我们可以直接暴力枚举寻找 \(g\)

但我们除了判断 \(g^{\phi(p)}\equiv 1\ (mod\ p)\) 外,还要判断小于 \(\phi(p)\) 的数 \(k\) 都满足 \(g^k\not \equiv 1\ (mod\ p)\)

证明指出,若 \(g^k\equiv 1\ (mod\ p)\),那么一定满足 \(k|\phi(p)\)

\(\phi(n)\) 的质因数为 \(\{p_1,p_2,p_3,...,p_n\}\)

我们只需要验证 \(g^{\frac{\phi(n)}{p_i}}\not \equiv 1\ (mod\ p)\) 即可

这个过程的复杂度为 \(O(n^{0.25}\ log\ n)\)

一般题目中求了最小原根就足够了,但本题还要求剩下的原根

假设我们已经求出了最小原根 \(g\) ,那么有一条定理为:原根 \(g\) 满足 \(g^k\) 的阶为 \(\frac{\phi(p)}{gcd(\phi(p), k)}\)

也就是说,只有当 \(gcd(\phi(p), k)=1\) 时,\(g^k\ mod\ p\)\(p\) 的原根之一;而一个数如果有原根,则有 \(\phi(\phi(n))\)

那我们就考虑枚举 \(1\) ~ \(\phi(p)\) 判断是否满足上述 \(gcd(\phi(p), k)=1\)

复杂度为 \(O(\phi(n)\ log\ \phi(n))\)

最后对答案进行排序即可

代码


2. NTT

注:这里默认 \(p\) 为奇质数

我们先回顾一下 FFT单位根都要满足些什么条件:

\(n\) 个根的值互不相同

显然,根据原根的定义,我们一定有 \(g^0\) ~ \(g^{(p-1)}\) 互不相同

\(\omega_n^k=\omega_{2n}^{2k}\)

根据我们的定义 \(G_n^k=g^{\frac{p-1}{n}\times k}\)

所以有 \(G^{2k}_{2n}=G_n^k\)

\(\omega_n^k=-\omega_n^{k+n/2}\)

我们有 \(G_n^n=(G_n^1)^n=g^{p-1}=1\ (mod\ p)\) (根据费马小定理

又因为 \((G_n^{n/2})^2=G_n^n=1\),所以 \(G_n^{n/2}=\pm1\),又根据性质①,知 \(G_n^{n/2}=-1\)

因此我们有 \(G_n^{k+n/2}=G_n^k\times G_n^k=-G_n^k\)

\(\sum_{i=0}^{n-1} (\omega_n^k)^i=0\)

这个是为了证明 IDFT 时直接将 \(\omega_n^1\) 换成 \(\omega_n^{-1}\),最后答案再除以 \(n\) 是正确的

用同样的套路,我们有

\[\sum_{i=0}^{n-1} (G_n^k)^i=\frac{(G_n^k)^n-1}{G_n^k-1}=0 \]

至此,我们的原根 \(G\) 都完美地符合了单位根 \(\omega\) 的所有性质

但由性质③,我们看出 \(p-1\) 必须要是 \(2\) 的整次幂的倍数才能正常分治,一次我们的模数 \(p\) 必须是 \(k\times 2^m+1\) 这样的形式

因此 NTT 有以下的限制条件:

    1. 系数必须为整数
    1. 在模意义下运算,而且对模数的要求较高,为 \(k\times 2^m+1\) 的奇质数

但不得不说,NTT 保证了精度,以及它不需要借助三角函数让复杂度降低不少的优点是很突出的

代码


附上常见质数的原根

posted @ 2022-04-07 15:52  zuytong  阅读(115)  评论(0编辑  收藏  举报