0%

NTT学习笔记

NTT 的中文名称为快速数论变换,英文全称为 Number-theoretic transform,是 FFT 在数论基础上的实现,可以避免 FFT 的复数运算中的精度损失。

NTT 实际上是将 FFT 中的复数运算巧妙的替换为了整数运算。

原根

若一个正整数 和一个质数 满足对于所有 的值互不相同。

NTT原理

实际上,NTT 就是选取了适当的模数以及任何一个这个质数的原根,并用一些整数代替了复数(被代替的就是上面的 )。

直接这样说估计没人懂,举个例子。

就以最常见的 NTT 模数 和它的原根(之一) 来举例。

首先一个比较重要的地方,就是 ,这是 NTT 模数的关键之一,这个模数减一必须是 的较大次幂的倍数。

假设现在要进行 NTT 的多项式共有 项(和 FFT 一样, 的整数次幂),那么用哪个数字代替 比较合适呢?

不难想到,用 代替 ,同理对于其他 ,用 代替 ,这样就大功告成。

此外将 FFT 的其他操作(加法,乘法,减法等)改成模意义下的运算,所有的复数都改成整数,就可以了。

同理,假如使用一个质数 与它的原根 进行 NTT 时,使用 代替 即可。

正确性证明

不难发现,FFT 能够快速运算的运算在于复数的那三个性质。

同时,这也是 NTT 可以快速计算的关键,因为我们刚刚对于 的取值也满足这些性质!

下面我们来一条一条看。 证明: 注意,对于所有质数 都有


证明:


证明:

注意到一定会有

所以这个式子的值为

额, 似乎不算很显然,我们来证一下。

首先,根据原根的性质,我们知道对于 ,肯定恰好存在一个 使得

那么我们就知道,一定会有

同时,我们知道,一定恰好存在一个 使得 (还是原根的性质),而我们知道

所以就会有

这个方程一共有两个解,

显然, 不满足条件,因为

所以一定会有

NTT 就说完了。

提交记录

加上快读和快写还能快一点


下面是几个模板呀。

多项式求逆

P4238 【模板】多项式乘法逆

设原多项式为 ,它的逆为

,它的逆为

则一定会有以下几个性质: 则由 可得: 两边同时乘上 。(其实只有一边 也就是说,只要我们知道了 ,就可以在 的时间内把 算出来(NTT 把上面的式子卷一下)。

时间复杂度

提交记录

任意模数多项式乘法

P4245 【模板】任意模数多项式乘法

我们可以发现,这道题里面的模数可能不能满足之前我们对模数的要求,甚至不是一个质数,所以我们不能直接进行 NTT。

这里我使用的是三模数 NTT。

具体做法就是我们找三个可以进行的 NTT 的模数,然后做三遍 NTT,最后使用 CRT 求出答案。

这里我使用的三个模数分别为

直接做就可以了。

然而最后的 CRT 还是有一些细节的(),因为模数个数比较少,所以我们可以手颓柿子:

首先我们知道这些:

所以一定存在三个自然数 使得 这样我们就可以求出 的值了,不妨记作 ,则存在 使得 都知道了,我们就可以求出 了。

当然,你也可以使用 __int128来做。

中间的取模还是有很多细节的,具体可以看代码。

提交记录

把三个数字写成一个结构体,一起 NTT 还能更快亿点,真的是亿点。

提交记录

分治NTT

P4721 【模板】分治 FFT

虽然写的是 FFT,但实际上是分治 NTT...

我们要求出一个满足条件的多项式 ,但是 的值和 有关。

考虑进行分治。

假设我们现在分治到了一个区间 ,下一步肯定是分治 这个区间。

然后呢?我们需要快速处理区间 的贡献。

实际上 NTT 卷一下就可以了。

时间复杂度

提交记录

例题

hdu7162题解