跳过并跳转到主要内容
BigO

快速幂取模

快速幂取模通过二进制拆分指数,将大指数幂运算的时间复杂度降至 O (log n),在每一步运算中同步做取模操作,避免数值溢出,用来高效求解 a 的 b 次方对 m 取模的结果。

基础算法1分钟阅读
模幂运算(快速幂取模),时间复杂度 O(log N)
模幂运算(快速幂取模),时间复杂度 O(log N)

快速幂取模(Modular Exponentiation) 是快速幂算法在实际工程和算法竞赛中最常见的形态。

它专门用来高效计算类似 (ab)(modm)(a^b) \pmod m 的问题,即求 aa 的 bb 次方对 mm 取模的结果。

在计算机中,如果不做处理直接算 aba^b:

  • 当 a=2,b=100a = 2, b = 100 时,21002^{100} 已经高达 1.26×10301.26 \times 10^{30},早已远超 64 位整型(long long / uint64_64)的表示上限,导致整型溢出。
  • 即便 Python 这种支持高精度大数的语言不会溢出,上千位甚至上万位的超大数乘法也会严重拖慢计算速度,耗尽内存。

根据模算术性质,乘积的模等于模的乘积:

(A×B)(modm)=[(A(modm))×(B(modm))](modm)(A \times B) \pmod m = [(A \pmod m) \times (B \pmod m)] \pmod m

这意味着:我们不需要等到整个指数算完再取模,而是在乘法执行的每一步都顺手取模。这样能把中间变量一直控制在 [0,m−1][0, m-1] 的安全范围内,完全杜绝溢出问题!

快速幂取模把指数 bb 看作二进制数。

以计算 313(mod7)3^{13} \pmod 7 为例:

  1. 指数 1313 的二进制是 (1101)2(1101)_2,即 13=8+4+0+113 = 8 + 4 + 0 + 1。
  2. 所以 313=38×34×313^{13} = 3^8 \times 3^4 \times 3^1。
  3. 算法从最低位向最高位扫描 bb:
    • 第 0 位(1): 包含 313^1,答案累乘 313^1,底数翻倍成 32(mod7)3^2 \pmod 7。
    • 第 1 位(0): 不包含 323^2,答案不变,底数翻倍成 34(mod7)3^4 \pmod 7。
    • 第 2 位(1): 包含 343^4,答案累乘 343^4,底数翻倍成 38(mod7)3^8 \pmod 7。
    • 第 3 位(1): 包含 383^8,答案累乘 383^8。

每一步的累乘和底数自乘,都立刻对 mm 取模。

在实现时,有两个极易被忽视的坑点需要特别注意:

  1. 防止 a≥ma \ge m:传入前先做 a = a % m。
  2. 中间乘法溢出:两个小于 mm 的数相乘,最大可能达到 (m−1)2(m-1)^2。如果 m≈2×109m \approx 2 \times 10^9,乘积就会达到 4×10184 \times 10^{18},必须用 64 位整数(如 C++ 的 long long)来存储中间结果。
#include <iostream>
// 计算 (a^b) % m
long long fast_power_mod(long long a, long long b, long long m) {
long long ans = 1;
a %= m; // 防止 a 本身比 m 大
while (b > 0) {
// 如果 b 的当前二进制最低位为 1
if (b & 1) {
ans = (ans * a) % m; // 累乘当前权重的底数,并取模
}
a = (a * a) % m; // 底数自乘翻倍,并取模
b >>= 1; // b 右移一位,相当于 b /= 2
}
return ans;
}
int main() {
// 示例:计算 (2^1000) % 1000000007
std::cout << fast_power_mod(2, 1000, 1000000007) << std::endl;
return 0;
}

指标复杂度 / 描述
时间复杂度O(log⁡b)O(\log b) — 循环次数仅取决于 bb 的二进制位数。
空间复杂度O(1)O(1) — 仅需几个常数级别的变量存放中间值。

  1. 密码学(RSA 加密算法): RSA 的核心解密/加密公式就是大数快速幂取模,例如 C=Me(modn)C = M^e \pmod n,其中指数 ee 和模数 nn 通常长达 2048 位。
  2. 求乘法逆元: 基于费马小定理(pp 为质数时,ap−1≡1(modp)a^{p-1} \equiv 1 \pmod p),取模意义下的逆元 a−1(modp)a^{-1} \pmod p 可以通过计算 ap−2(modp)a^{p-2} \pmod p 直接获得。
  3. 米勒-拉宾(Miller-Rabin)素数测试: 极其高效的大数概率素数检测算法,核心依赖快速幂取模。

© 2026 三七开 · 一方通行,只管向前。

旅途由 Astro 驱动 · 主题 Chirping Astro