快速幂
快速幂 #
如何快速求 $a^b$($a,b\in\mathbb{Z}$)?
递归写法 #
根据乘方公式 $a^{m+n}=a^m\cdot a^n$,有:
$$a^b=\left\{\begin{aligned} &a^{\left\lfloor b/2\right\rfloor}\cdot a^{\left\lfloor b/2\right\rfloor} && b=2k\\ &a^{\left\lfloor b/2\right\rfloor}\cdot a^{\left\lfloor b/2\right\rfloor}\cdot a && b=2k+1 \end{aligned}\right. ,k\in\mathbb{Z}$$
边界条件 | 时间复杂度 |
---|---|
$a^0=1$ | $O(\log{b})$ |
typedef long long LL;
LL Pow(LL a, LL b) {
if(!b) return 1; // 边界条件
LL res = Pow(a, b / 2);
if(b % 2 == 0) // b 是偶数
return res * res;
else // b 是奇数
return res * res * a;
}
递推写法 #
若 $b$ 在二进制下的第 $k_1,k_2,k_3,\cdots$ 位为 $1$,则 $b=2^{k_1}+2^{k_2}+2^{k_3}+\cdots(k_i≤\log{b})$.
举个例子,$(14)_{10}=(1011)_2$,二进制下 $14$ 的第 $0,1,3$ 位都为 $1$,那么 $14=2^0+2^1+2^3$.
将 $b=2^{k_1}+2^{k_2}+2^{k_3}+\cdots$ 代入 $a^b$:
$$\begin{aligned} a^b&=a^{\Large(2^{ k_1}+2^{ k_2}+2^{ k_3}+\cdots)}\\ &=a^{2^{k_1}}\cdot a^{2^{k_2}}\cdot a^{2^{k_3}}\cdot \ \cdots \end{aligned}$$
扫描 $b$ 的每个二进制位,如果第 $k$ 位是 $1$,则将答案乘上 $a^{2^k}$.
时间复杂度为 $O(\log{b})$.
typedef long long LL;
LL Pow(LL a, LL b) {
LL res = 1;
while(b) {
if(b % 2 == 1) // 二进制下该位为 1
res *= a;
a *= a, b /= 2;
}
return res;
}