快速幂 详解

快速幂算法详解

快速幂(Exponentiation by Squaring)是一种高效计算 abmod  ca^b \mod cabmodc 的方法,特别适用于处理大整数幂的场景。


1. 什么是快速幂?

快速幂的核心思想是将幂次拆分成二进制形式,通过平方和乘法逐步计算结果,而不是直接进行 bbb 次乘法。其时间复杂度从普通幂的 O(b)O(b)O(b) 降低到 O(log⁡b)O(\log b)O(logb)


2. 数学基础

幂运算的规律

对于一个数 aaa 和整数幂 bbb

  • 如果 bbb 是偶数:ab=(ab/2)2a^b = (a^{b/2})^2ab=(ab/2)2
  • 如果 bbb 是奇数:ab=a⋅ab−1a^b = a \cdot a^{b-1}ab=aab1

3. 快速幂的思想

通过幂次的二进制拆解,可以将幂次逐步减少:

  • 偶数幂:我们只需平方当前底数。
  • 奇数幂:先记录当前底数为部分结果,然后减少幂次(变为偶数)。

快速幂的分解过程

假设 b=13b = 13b=13,二进制为 110111011101,我们计算 a13a^{13}a13

  1. 131313 拆解为 a13=a8⋅a4⋅a1a^{13} = a^{8} \cdot a^{4} \cdot a^{1}a13=a8a4a1(二进制中为 1 的位对应的幂次)。
  2. 通过平方底数逐步计算:
    • a1=aa^1 = aa1=a
    • a2=a⋅aa^2 = a \cdot aa2=aa
    • a4=(a2)2a^4 = (a^2)^2a4=(a2)2
    • a8=(a4)2a^8 = (a^4)^2a8=(a4)2
  3. 将对应的幂次相乘即可。

4. 快速幂实现

4.1 递归实现

递归方式按照 bbb 的奇偶性进行拆解。

代码实现
public class FastPower {
    public static long fastPower(long a, long b, long mod) {
        if (b == 0) return 1; // 任何数的 0 次幂是 1

        long half = fastPower(a, b / 2, mod); // 递归计算一半的幂
        long result = (half * half) % mod; // 平方取模

        // 如果 b 是奇数,还需要多乘一个 a
        if (b % 2 != 0) {
            result = (result * a) % mod;
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(fastPower(2, 10, 1000000007)); // 输出 1024
    }
}
流程解析
  • 如果 b=0b = 0b=0,返回 111
  • 否则递归计算 ab/2a^{b/2}ab/2
  • 将其平方,如果 bbb 是奇数,则额外乘以 aaa

4.2 迭代实现

迭代方式直接通过 bbb 的二进制位逐位计算。

代码实现
public class FastPower {
    public static long fastPower(long a, long b, long mod) {
        long result = 1; // 初始化结果为 1
        long base = a % mod; // 计算 a 的初始模

        while (b > 0) {
            // 如果 b 的当前位是 1,将当前 base 累乘到结果
            if ((b & 1) == 1) {
                result = (result * base) % mod;
            }
            base = (base * base) % mod; // 底数平方
            b >>= 1; // b 右移一位,相当于 b // 2
        }

        return result;
    }

    public static void main(String[] args) {
        System.out.println(fastPower(2, 10, 1000000007)); // 输出 1024
        System.out.println(fastPower(2, 1000, 1000000007)); // 输出大数结果
    }
}
流程解析
  • 初始化 result = 1base = a % mod
  • 遍历幂次的二进制表示(通过右移逐步处理)。
  • 如果当前位为 1,累乘当前 baseresult
  • 每次循环后,base 自身平方,b 右移一位。

5. 示例分析

示例 1:普通幂运算

计算 2102^{10}210,无取模:

  • b=10b = 10b=10,二进制为 1010
  • 拆解为 210=(28)⋅(22)2^{10} = (2^8) \cdot (2^2)210=(28)(22)
  • 迭代过程:

以下是 快速幂算法在计算 2102^{10}210 的每一步执行过程中的 b(当前幂次的二进制表示)、base(当前底数)、result(累积结果)的状态变化表:


初始值:

  • b: 1010 (二进制表示 10)
  • base: 2
  • result: 1

迭代过程:

步骤b (二进制)b (十进制)最低位操作baseresult
初始值1010100不更新 resultbase = base^241
第 1 步010151累乘到 result = result * base,平方 base164
第 2 步001020不更新 resultbase = base^22564
第 3 步000111累乘到 result = result * base,平方 base655361024
结束00000-停止循环-1024

每一步详细解析

初始值:
  • b = 1010,最低位为 0
  • 因为最低位为 0,不更新 result
  • base 平方:base=22=4base = 2^2 = 4base=22=4

第 1 步:
  • b = 0101,最低位为 1
  • 累乘到 resultresult=1⋅4=4result = 1 \cdot 4 = 4result=14=4
  • base 平方:base=42=16base = 4^2 = 16base=42=16
  • 右移 bb = 0010

第 2 步:
  • b = 0010,最低位为 0
  • 因为最低位为 0,不更新 result
  • base 平方:base=162=256base = 16^2 = 256base=162=256
  • 右移 bb = 0001

第 3 步:
  • b = 0001,最低位为 1
  • 累乘到 resultresult=4⋅256=1024result = 4 \cdot 256 = 1024result=4256=1024
  • base 平方:base=2562=65536base = 256^2 = 65536base=2562=65536(虽然此时不会再用到 base)。
  • 右移 bb = 0000

结束:
  • b = 0000,停止迭代。
  • 最终结果:result=1024result = 1024result=1024

总结

在快速幂算法中,每一位的处理都是通过平方更新 base,并根据最低位的值决定是否累乘到 result。这种方法使计算效率达到 O(log⁡b)O(\log b)O(logb)

示例 2:幂模运算

计算 210mod  72^{10} \mod 7210mod7

  • b=10b = 10b=10,二进制为 1010
  • 拆解为 210mod  7=(28mod  7)⋅(22mod  7)mod  72^{10} \mod 7 = (2^8 \mod 7) \cdot (2^2 \mod 7) \mod 7210mod7=(28mod7)(22mod7)mod7
  • 迭代过程:
    • 初始:result = 1base = 2
    • 第 1 步:b=1010b = 1010b=1010,最低位为 0,不更新 result
    • 第 2 步:b=0101b = 0101b=0101,最低位为 1,result = 2
    • 第 3 步:b=0010b = 0010b=0010,最低位为 0,不更新 result
    • 第 4 步:b=0001b = 0001b=0001,最低位为 1,result = 4

结果为 4


6. 时间与空间复杂度

时间复杂度

快速幂算法的时间复杂度为 O(log⁡b)O(\log b)O(logb),因为每次运算将 bbb 减半(右移一位)。

空间复杂度

  • 递归实现:需要 O(log⁡b)O(\log b)O(logb) 的递归栈空间。
  • 迭代实现:仅使用常数空间,空间复杂度为 O(1)O(1)O(1)

7. 快速幂的应用场景

  1. 大数幂运算

    • 例如 210002^{1000}21000,直接计算会溢出,而快速幂可以通过取模解决。
  2. 密码学

    • 在 RSA 等加密算法中,经常需要计算 abmod  ca^b \mod cabmodc,快速幂是核心部分。
  3. 组合数学与数论

    • 计算模逆元(利用费马小定理:a−1≡ap−2mod  pa^{-1} \equiv a^{p-2} \mod pa1ap2modpppp 为质数)。
    • 处理排列、组合时涉及的幂运算。

8. 总结

  • 核心思想:利用幂的二进制拆解,通过平方和乘法快速计算结果。
  • 递归实现:简单易懂,但需要栈空间。
  • 迭代实现:效率高,占用空间少,更常用。
  • 时间复杂度O(log⁡b)O(\log b)O(logb),适用于大规模运算场景。

掌握快速幂算法是学习数学、算法与密码学的基础技能,非常重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞滕人生TYF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值