快速幂模m算法(C++)
解决问题:求解 a b m o d m a^b\mod m abmodm,其中b很大,需要缩短时间。
主要思路:求不要重复求 a i a^i ai
解决方案1
倒推:不递归
b
=
(
b
n
,
.
.
.
b
1
,
b
0
)
2
=
b
0
∗
2
0
+
b
1
∗
2
1
.
.
.
+
b
n
∗
2
n
b=(b_n,...b_1,b_0)_2=b_0*2^0+b_1*2^1...+b_n*2^n
b=(bn,...b1,b0)2=b0∗20+b1∗21...+bn∗2n
a
b
=
a
b
0
∗
2
0
×
.
.
.
×
a
b
n
∗
2
n
a^b=a^{b_0*2^0}\times...\times a^{b_n*2^n}
ab=ab0∗20×...×abn∗2n
这样每次只需要先求出
a
2
i
−
1
a^{2^{i-1}}
a2i−1就可以得到
a
2
i
a^{2^{i}}
a2i了;
C++代码附上:
int m = 10;
int pow(int a, int b) {
int ans = 1;
while (b)
{
if (b & 1)ans = ans * a % m;//如果b_i为1,就要相乘
a = a * a % m;//上一个a的平方
b >>= 1;//b(当成是二进制)向右移动一位
}
return ans;
}
解决方案2
顺推:递归
如果b为偶数,
a
b
=
(
a
b
/
2
)
2
a^b=(a^{b/2})^2
ab=(ab/2)2,
如果b为奇数,
a
b
=
(
a
b
−
1
)
∗
a
a^b=(a^{b-1})*a
ab=(ab−1)∗a,
一直这么分解下去,直到b等于1,可以得到a;
递归版本:
#include <iostream>
using namespace std;
int m = 10;
int pow(int a, int b) {
if (b == 1)
return a;
else if (b % 2 == 1)
return a * pow(a, b-1)%m;
else
{
int num = pow(a, b >>1) % m;
return num * num % m;
}
}
备注:
- 如果是做程序设计题目,记得把int换成long long;
- 递归算法固然比非递归时间要慢一点