- 快速幂:
传统求a^b非常的耗时间,那么有没有一种更快的方法去求这个呢
下面介绍一次快速幂:
以求a的b次方来介绍
把b转换成二进制数
以a^11为例:
b的二进制数为1011,二进制从右向左算,但乘出来的顺序是 a(20)*a(21)*a(23),是从左向右的。我们不断的让base *= base目的是累乘,以便随时对ans做出贡献。
要理解base *= base这一步:因为base * base == base ^ 2,下一步再乘,就是(base ^ 2) * (base ^ 2) == base ^ 4,然后同理(base ^ 4) * (base ^ 4) == base ^ 8,由此可以做到base → base ^ 2 → base ^ 4 → base ^ 8 → base ^ 16 → base ^ 32…指数正好是 2 ^ i 。再看上面的例子,a¹¹= (a ^ 1) * (a ^ 2) * (a ^ 8),这三项就可以完美解决了,快速幂就是这样。
代码:
long long ksm(long long a,long long b)
{
int ans = 1,base = a;
while(b != 0){
if(b & 1 != 0){
ans *= base;
}
base *= base;
b >>= 1;
}
return ans;
}
- 快速乘
快速乘与快速幂的思想基本一致,都是把b转化为二进制,ab转化为多个式子相加的形式,在计算机中加法运算不乘法运算快。*
当ab的计算结果爆出long long的范围是,可以用快速乘来求解,不仅降低时间复杂度,而且节省空间。
例:
inline ll mult_mod(ll a, ll b, ll m)
{
ll res = 0;
while(b){
if(b&1) res = (res+a)%m;
a = (a+a)%m;
b >>= 1;
}
return res;
}