学到一个黑科技,但是有点抽象。
这波好好讲讲什么是快速幂吧。🧙♂️
快速幂,也称为“二分幂”或“平方幂”,是一种高效的计算大整数幂的方法。与普通方法相比,它能显著减少乘法的次数。
📝 基本思想:
-
将指数表示为二进制形式,然后使用这种表示来减少幂的计算次数。
-
我们不断地取指数的一半来降低问题规模,这是“分治”的思想。
🔍 算法步骤:
- 将幂指数
b
转化为二进制形式。 - 对于
b
的每一个二进制位(从最低位到最高位),我们将a
自乘。当遇到b
的一个二进制位为1时,将当前的a
乘到结果中。 - 每处理完
b
的一个二进制位,a
自乘。
😎 为什么它有效?
想象这样一个情况: 计算 a^13
。 13 可以表示为二进制 1101
。所以:
a^13 = a^(2^3 + 2^2 + 2^0)
= a^(2^3) * a^(2^2) * a^(2^0)
数学公式的形式如下:
a
13
=
a
2
3
+
2
2
+
2
0
=
a
2
3
×
a
2
2
×
0
⋅
a
2
1
×
a
2
0
a^{13} = a^{2^3 + 2^2 + 2^0} = a^{2^3} \times a^{2^2} \times 0·a^{2^1} \times a^{2^0}
a13=a23+22+20=a23×a22×0⋅a21×a20
这里使用了幂的乘法规则
(
a
m
+
n
=
a
m
×
a
n
)
( a^{m+n} = a^m \times a^n )
(am+n=am×an)
通过这种方式,我们只需要3次乘法就可以得到答案,而不是普通方法的12次。
🎓 代码实现:
int quick_pow(int a, int b) {
int ans = 1;
while (b) {
if (b & 1) {
ans *= a; // 如果当前二进制位为1,则乘到结果中
}
a *= a; // a自乘
b >>= 1; // 右移一位,相当于b除以2
}
return ans;
}
(・∀・(・∀・(・∀・*)为什么自乘?
其实这里a每次上升一位就要迭代,变成
a
2
a^2
a2
,这样在迭代2次之后,就是
(
a
2
)
2
(a^2)^2
(a2)2
即
a
2
×
2
a^{2 \times 2}
a2×2
因此,迭代n次后,就是
a
2
n
a^{2^n}
a2n
而if
那一块的判断1 or 0就是决定是否乘上这一项。
如果你在编程中还需要考虑取模的操作,比如求(a^b \mod m),那在乘法操作后直接取模即可,这样可以防止整数溢出。
是不是一下子清晰明了咯?😋