快速幂(二分幂)

快速幂(二分幂)

问题

给定正整数a、b、m,求 a b % m a^b\%m ab%m

方法一

运用递归思想,考虑以下两个步骤:

  • b为奇数,则 a b = a ∗ a b 2 ∗ a b 2 a^b = a * a^{\frac{b}{2}} * a^{\frac{b}{2}} ab=aa2ba2b
  • b为偶数,则 a b = a b 2 ∗ a b 2 a^b = a^{\frac{b}{2}} * a^{\frac{b}{2}} ab=a2ba2b

时间复杂度为 O ( log ⁡ b ) O(\log{b}) O(logb)

typedef long long LL;

LL binaryPow(LL a, LL b, LL m)
{
    if (b == 0)         // 递归边界
        return 1;
    
    // 注意不能直接return函数乘积,不然会造成重复计算
    LL p = binaryPow(a, b / 2, m);  
    if (b % 2 == 0)     
        return p * p % m;        
    else                
        return a * p * p % m;
}

方法二

运用迭代思想,将b用二进制表示,那么可以得到 a b = ∏ a 2 i ∗ k i a^b = \prod a^{2^i}*k_i ab=a2iki i i i 表示b二进制从低位到高位的位号, k i k_i ki 表示当前位的数字是0或1。

typedef long long LL;

LL binaryPow(LL a, LL b, LL m)
{
    LL ans = 1;             // 记录结果
    while (b)
    {
        if (b & 1)          // b二进制的末位为1,则累乘
            ans = ans * a % m;
        a = a * a % m;      // b每右移一位,a的值都要变化
        b = b >> 1;         // b右移一位
    }
    return ans;
}

你可能感兴趣的:(Algorithm,-,cpp)