对于一个运算:327,乘27个3速度是比较慢的。快速幂 可以将O(n)的复杂度降到O(logn)的复杂度。
思想:
我们把27转换为二进制数:
(
27
)
D
=
(
11011
)
B
(27)_D = (11011)_B
(27)D=(11011)B,则:
3
27
=
3
1
∗
2
0
+
1
∗
2
1
+
0
∗
2
2
+
1
∗
2
3
+
1
∗
2
4
3^{27} = 3^{1 *2^0 + 1*2^1 + 0*2^2 + 1*2^3 + 1*2^4}
327=31∗20+1∗21+0∗22+1∗23+1∗24
我们会发现:当二进制位为0的时候,最后的结果中是不用乘上这一项的;而当二进制位为1的时候,我们最后的结果是要乘上这一项的,并且这一项的权值是前一项的两倍,比如:23和22,而表现在幂指数上就是平方:
3
2
3
=
3
2
2
∗
3
2
2
3^{2^3} = 3^{2^2} * 3^{2^2}
323=322∗322
正因为乘积的一个因子可以由前一项平方得到,而不需要每次都是乘3,所以可以把时间复杂度降低到O(logn)级别。
模板如下:
int pow(int a, int b, int mod){
int ans = 1; // 初始答案为1,把因子依次乘到ans上去
while(b){
// * 1ll是指乘上一个long long类型的1,防止爆int
if(b & 1) ans = ans * 1ll * a % mod; // 当前位是1话,把这一项因子乘到结果中去;如果是0,则不用计算
a = a * 1ll * a % mod; // 平方得到下一项
b >>= 1; // 当前位算完了之后,把它右移,将下一位变成当前位
}
return ans;
}