问题引入:
求ab %c的值
(假设ans=ab)
其中a,b,c为整数,且a>0,c<109,b<1018
算法设计:
对于这个问题,我们首先想到的是暴力算法,for循环循环b次,最后对c取模,但这样做会有两个缺陷
第一:时间复杂度为o(b),如果b很大,那么计算机需要很长时间计算
第二:即便是long long型数据,a^b也很容易超过long long 的最大值
那么应该如何优化呢?
首先有这样有一个性质:
(ab)%p=[(a%p)(b%p)]%p
(可设a=k1p+q1,b=k2p+q2来证明)
通过取模运算的这个性质,我们可以每乘一次a,就对其取模,以此可以解决数据爆掉的问题
但是时间复杂度依然是O(b)
如何继续优化?
我们考虑手动计算3^10的过程
我们是310=95=9*812
即:当指数b为偶数时,我们直接将指数除以2,然后将底数a平方
当指数b为奇数时,我们将ans先乘以底数,再将指数b整除2(即舍去小数部分),然后将底数平方
实际上,这样做,我们每次将b整除2,因此如果把b写成2^n的形式,那么只需要n次,即时间复杂度为O(log2(b))
代码如下:
long long fast_power(long long a, long long b, long long c)//快速幂的实现
{
long long ans = 1;
while (b)
{
if (b % 2 == 1)//如果b是奇数,需要将ans先乘a,其他操作与b为偶数的情况一样
ans *= a;
a *= a;
b /= 2;
}
}
那么加上mod c呢?
long long fast_power(long long a, long long b, long