[NTT]任意模数NTT

NTT(Number Theoretic Transform)是一种基于数论的多项式算法,适用于整数计算,避免了浮点数运算中可能出现的问题。本文介绍了NTT的基础知识,包括阶、原根,并提供了一个包含普通NTT和任意模数NTT(三模数NTT)的Code示例,适用于处理需要取模的复杂计算场景。

题目

洛谷

NTT

FFT可以帮助我们快速地将多项式从系数表达变换成点值表达。但由于涉及浮点数运算,我们需要对一些数取模时,不能一边计算一边取模,所以有可能会爆炸。而且我们有时候也会因此丢失精度,导致结果错误。所以,我们就要引入NTT算法。

NTT是利用一些特殊的模数,基于数论来进行变换的一种基于FFT的多项式算法。过程中所使用的都是整数,所以不存在这些问题。

前备知识

对于 gcd ⁡ ( x , n ) = 1 \gcd(x, n) = 1 gcd(x,n)=1,满足 x k ≡ 1 ( m o d   m ) x^k \equiv 1 (mod \ m) xk1(mod m),最小的 k k k就叫做 x x x n n n的阶。

原根

设正整数 m m m,整数 a a a,若 a a a m m m的阶为 ϕ m \phi m ϕm,则称 a a a为模 m m m的一个原根。

常用原根表

   质 数                                            原 根 \ \ 质数 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 原根                                             
   3                                                  2 \ \ 3\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2   3                                                2
   5                                                  2 \ \ 5\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2   5                                                2
   97                                                5 \ \ 97\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 5   97                                              5
   193                                              5 \ \ 193\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 5   193                                            5
   257                                              3 \ \ 257\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 3   257                                            3
   7681                                            17 \ \ 7681\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 17   7681                                          17
   12289                                          11 \ \ 12289\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 11   12289                                        11
   40961                                          3 \ \ 40961\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 3   40961   

快速傅里叶变换(FFT)是处理数字信号的重要工具,而数论变换(NTT)则是在特定模数下进行的快速变换,常用于大整数乘法或多项式乘法中,以避免浮点数精度问题。NTT 依赖于原根和模数的性质,其基本思想与 FFT 类似,但所有运算都在模数下进行。 以下是一个 NTT 的基本实现示例,适用于模数为形如 $ p = r \cdot 2^k + 1 $ 的质数,并且要求输入长度为 $ 2 $ 的幂: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 998244353, G = 3, MAXN = (1 << 21); ll pow_mod(ll a, ll b, ll mod) { ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; } void ntt(vector<ll>& a, int op) { int n = a.size(); vector<ll> b = a; for (int i = 0; i < n; i++) { int rev = 0; for (int j = 0; j < log2(n); j++) rev |= ((i >> j) & 1) << (log2(n) - 1 - j); b[rev] = a[i]; } a = b; for (int h = 2; h <= n; h <<= 1) { ll gn = pow_mod(G, (MOD - 1) / h, MOD); for (int i = 0; i < n; i += h) { ll g = 1; for (int j = 0; j < h / 2; j++) { ll u = a[i + j], v = a[i + j + h / 2] * g % MOD; a[i + j] = (u + v) % MOD; a[i + j + h / 2] = (u - v + MOD) % MOD; g = g * gn % MOD; } } } if (op == -1) { reverse(a.begin() + 1, a.end()); ll inv = pow_mod(n, MOD - 2, MOD); for (int i = 0; i < n; i++) a[i] = a[i] * inv % MOD; } } vector<ll> multiply(vector<ll> a, vector<ll> b) { int n = 1; while (n < a.size() + b.size()) n <<= 1; a.resize(n), b.resize(n); ntt(a, 1), ntt(b, 1); for (int i = 0; i < n; i++) a[i] = a[i] * b[i] % MOD; ntt(a, -1); return a; } int main() { vector<ll> a = {1, 2, 3}, b = {4, 5, 6}; vector<ll> res = multiply(a, b); for (ll x : res) cout << x << " "; return 0; } ``` ### NTT 的应用 - **大整数乘法**:将两个大整数表示为多项式,通过 NTT 实现快速乘法。 - **卷积计算**:在信号处理中,两个信号的卷积可通过 NTT 实现快速计算。 - **多项式求逆、开方、指数、对数等操作**:这些操作在现代算法竞赛中广泛使用。 ### 学习资源推荐 1. **《算法导论》**:第 30 章详细讲解了快速傅里叶变换,NTT 可视为其模运算下的变种。 2. **OI Wiki**:提供了 NTT 的数学基础、实现细节和典型应用。 3. **Codeforces 和 AtCoder**:许多竞赛题涉及 NTT 的使用,如多项式乘法、组合数学问题等。 4. **洛谷题库**: - P3803 【模板】多项式乘法(FFT/NTT) - P4245 【模板】任意模数多项式乘法(三模数 NTT) - P4721 【模板】分治 FFT ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值