快速幂
思想:
常规计算
a
n
a^n
an,使用累乘n个a的方法,时间复杂度是
O
(
n
)
O(n)
O(n)。使用快速幂可把计算
a
n
a^n
an的时间复杂度降到
O
(
l
o
g
n
)
O(log_n)
O(logn)。
为降低计算量,我们可以先计算出
a
2
a^2
a2,再累乘
a
2
a^2
a2 来计算
a
n
a^n
an,这样计算复杂度可降为
O
(
n
/
2
)
O(n/2)
O(n/2)。再以
2
11
2^{11}
211 为例,11的二进制形式为1011(1+2+8),因此有
2
11
=
2
1
×
2
2
×
2
8
2^{11}=2^1×2^2 ×2^8
211=21×22×28,相较累乘11次2,这种方法仅累乘3次,可大大降低计算量。
代码:
- 二进制与运算符 &:可用于取出二进制某一位。
- 二进制左移一位 <<1:相当于乘2运算,比乘法速度快。
- pow()函数:参数与返回值都是double类型,计算int型幂时注意截断误差。
#include <bits/stdc++.h>
using namespace std;
// 暴力
int pow1(int a, int b){
int ans = 1;
while(b--) ans *= a;
return ans;
}
// 快速幂
int pow2(int a, int b){
int ans = 1, base = a;
while(b != 0){
if(b & 1 == 1) // b & 1:取出b二进制的最末一位
ans *= base;
// 每轮while循环b右移一位
// base对应二进制位的系数
base *= base;
b >>= 1;
}
return ans;
}
int main(){
int a = 2, b = 11;
cout << "pow():" << pow(a, b) << "\n";
cout << "暴力:" << pow1(a, b) << "\n";
cout << "快速幂:" << pow2(a, b) << "\n";
return 0;
}