快速求幂法
对于求一个数a的n次幂,我们第一想法就是调用包含在头文件cmath或math.h头文件下的pow(a, n)函数, 为了算法看起来简单用int代替大数模版。
循环求幂
最简单的实现就是用一个循环和一个变量,不断用变量乘上底数,当然,这样做的效率并不高O(N)。
#include<iostream>
using namespace std;
int pow1(int a, int b) {
int n = 1;
while(b--) n *= a;
return n;
}
int main() {
int a, b;
cin >> a >> b;
cout << pow1(a, b) << endl;
}
二分改进
求 3^5:
3^5 = 3^2 * 3^2 * 3.
同理 3^4:
3^4 = 3^2 * 3^2.
这样就根据奇数幂和偶数幂来分成了两半,故得到了两个公式:
x^n = x^(n/2) * x^(n/2). (n为偶数)
x^n = x^(n/2) * x^(n/2) * x. (n为奇数)
通过递归来实现:
#include<iostream>
using namespace std;
int pow2(int a, int b) {
if(b == 1) return a;
else if(b == 0) return 0;
if(b & 1) return pow2(a, b/2) * pow2(a, b/2) * a; //n为奇数
else return pow2(a, b/2) * pow2(a, b/2); //n为偶数
}
int main() {
int a, b;
cin >> a >> b;
cout << pow2(a, b) << endl;
}
//ps:b & 1表示了b的奇偶性,奇数返回1,偶数返回0;相当于b % 2 == 1;
经典快速幂
对于求5^999,可以用二分思想处理,还有就是用经典快速幂:
5^999 = 5^512 * 5^256 * 5^128 * 5^64 * 5^32 * 5^4 * 3.
把5^999的指数分解为底数为2的n次幂,512 = 2^9, 256 = 2^8……;
然后把999转换成2进制为1111100111
1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|---|
2^9 | 2^8 | 2^7 | 2^6 | 2^5 | 0 | 0 | 2^2 | 2^1 | 2^0 |
#include<iostream>
using namespace std;
int pow3(int x, int n) {
if(n==0) return 1;
else {
while(!(n & 1)) {
x *= x;
n >> = 1; //>>表示右移预算符,相当与n /= 2
}
}
int result = x;
n >>= 1;
while(n) {
x *= x; //此时因为循环前的n的右移,故要x^2
if(!(n & 1)) result *= x;
n >>= 1;
}
return result;
}
int main() {
int a, b;
cin >> a >> b;
cout << pow3(a, b) << endl;
}