快速幂
快速幂是我们解决中数论问题的基石让我们能以 \(O(logn)\) 的复杂度计算 \(a^n\)
快速幂的思想简单而言就是将 \(n\) 的二进制中所有的 \(1\) 代表的次幂乘起来比如计算 \(3^5,5=(101)_2\) ,则使用快速幂计算 \(3^5\) 的过程就是 \(3^{(1)_2}\times 3^{(100)_2}\)
参考代码如下:
int fp(int x, int y) {int res = 1;for (; y; y >>= 1, x = 1ll * x * x % mod) {if (y & 1) {res = 1ll * res * x % mod;}}
}
同余
设整数 \(m\mid(a-b)\) ,则我们称 \(\alpha\) 同余于 \(b\) 模 \(m\) ,记作 \(a\equiv b\pmod m.\)
同余可以理解为模意义下的相等.
同余满足如下性质:
- 线性运算:若 \(a \equiv b \pmod{m}\),$ c \equiv d \pmod{m} $ ,则 \(a \pm c \equiv b \pm d \pmod{m}\),\(a \times c \equiv b \times d \pmod{m}\)。
- 若 \(a \equiv b \pmod{m}\),\(k \in \mathbb{N}_{+}\),则 \(ak \equiv bk \pmod{mk}\)。
- 若 \(a \equiv b \pmod{m}\),\(d | m\),则 \(\frac{a}{d} \equiv \frac{b}{d} \pmod{\frac{m}{d}}\)。
同余类:设 \(m\in\mathbb{N}_+\) ,则可以将全体整数分为 \(m\) 个划分,每个集合满足其中的数模 \(m\) 均同
余,将这 \(m\) 个集合称为模 \(m\) 的剩余类,用 \(r\bmod m\) 表示含有 \(r\) 的模 \(m\) 的剩余类。
完全剩余系:对 \(m\) 个整数 \(a_1,a_2,\ldots,a_m\) ,若对任意整数 \(x\) ,有且仅有一个数满足 \(a_i\equiv x({\mathrm{mod~}}m)\) ,则称这 \(m\) 个数为模 \(m\) 的完全剩余系.在 OI 中常用最小非负剩余系,即:
最大公约数(\(gcd\))
\(a\) 和 \(b\) 的最大公约数 \(\gcd(a,b)\) 定义为所有满足 \(c\mid a,c\mid b^1\) 的 \(c\) 的最大值(\(c\) 为 \(a,b\) 的公约数).最大公约数有
如下性质:
- 结合律:\(\gcd(a_1,a_2,\ldots,a_n)=\gcd(\gcd(a_1,a_2),\ldots,a_n)\)
- 分配律:\(\gcd(ma_1,ma_2,\ldots,ma_n)=m\gcd(a_1,a_2,\ldots,a_n).\)
最大公约数 \(gcd\) 与最小公倍数 \(lcm\) 有如下关系:
在 OI 中,我们通过辗转相除法的方法来求最大公约数.即 \(\gcd(a,b)=\gcd(b,a\) mod \(b)^3.\)
这个算法的时间复杂度是 \(O(\log a).\)
证明略.
代码如下:
int gcd(int a, int b) {reutrn b ? gcd(b, a % b) : a;
}
扩展欧几里得算法(Extended Euclidean Algorithm, Exgcd),常用于求不定方程 \(ax + by = gcd(a, b)\) 的一组解。具体流程如下:
设
由于 \(\text{gcd}(a, b) = \text{gcd}(b, a \mod b)\),于是
于是 \(x_1 = y_2\), \(y_1 = x_2 - \left\lfloor \frac{a}{b} \right\rfloor y_2\).
将 \(x_2, y_2\) 递归,直至 \(\text{gcd}\) 为 \(0\) 时将 \(x = 1, y = 0\) 代入计算即可。
参考代码如下:
int exgcd(int a, int b, int& x, int& y) {cout << x << " " << y << "\n";if (!b) {x = 1, y = 0;return a;}int ans = exgcd(b, a % b, x, y);int tmp = x;x = y;y = tmp - a / b * y;return ans;
}
费马小定理
·对素数\(p\)以及任意自然数 \(a\) ,有 \(a^p\equiv a\pmod{p}.\)
·对素数\(p\)以及与其互素的自然数 \(a\) ,有 \(a^{p-1}\equiv1\pmod{p}.\)
我们使用数学归纳法证明这一定理,对于 \(\alpha=1\) ,显然结论成立.假设 \(p\mid(a^p-a)\) ,现在讨论
\(a+1\) 时的情况,即要证明 \(p\mid((a+1)^p-(a+1)).\)
将右侧使用二项式定理展开,则
由于 \(p\) 是素数,故而对任意的 \(k,p\mid\binom pk.\) 由假设的结论可以得到 \(p\mid(a+1)^p-(a+1).\) 故费马小定理成立.
费马定理是欧拉定理:\(a^\varphi(m)\equiv1 \pmod m)(\gcd(a,m)=1)\) 的一个特殊情况,其中 \(\varphi(m)\) 是欧拉函数.
若 \(x\) 满足 \(ax \equiv 1 \pmod{b}\),则称 \(x\) 是在模 \(b\) 意义下 \(a\) 的乘法逆元,记作 \(a^{-1}\).
- 求逆元的方法:
- Exgcd 求逆元:相当于求 \(ax + by = 1\),要求 \(\gcd(a,b) = 1\)。
- 费马小定理求逆元:由 \(a^{p-1} \equiv 1 \pmod{p}\) 有 \(a^{-1} \equiv a^{p-2} \pmod{p}\),快速幂即可。要求 \(p\) 是素数。
- 线性求 \(1 \sim n\) 的逆元:令 \(p = kx + y\),则 \(k = \left\lfloor \frac{p}{x} \right\rfloor\)。有 \(kx + y \equiv 0 \pmod{p}\)。两边同时乘 \(x^{-1} \times y^{-1}\)。得到 \(x^{-1} \equiv -ky^{-1} \pmod{p}\)。递推即可。
void Inv(int n, int p) {inv[1] = 1;for (int i = 2; i <= n; ++i) {inv[i] = (long long)(p - p / i) * inv[p % i] % p;}
}