快速幂(二分幂)
问题
给定正整数a、b、m,求 ab%ma^b\%mab%m。
方法一
运用递归思想,考虑以下两个步骤:
- b为奇数,则 ab=a∗ab2∗ab2a^b = a * a^{\frac{b}{2}} * a^{\frac{b}{2}}ab=a∗a2b∗a2b
- b为偶数,则 ab=ab2∗ab2a^b = a^{\frac{b}{2}} * a^{\frac{b}{2}}ab=a2b∗a2b
时间复杂度为 O(logb)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用二进制表示,那么可以得到 ab=∏a2i∗kia^b = \prod a^{2^i}*k_iab=∏a2i∗ki,iii 表示b二进制从低位到高位的位号,kik_iki 表示当前位的数字是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;
}