快速幂+数组按位运算解决高精度幂运算

问题引入:

求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 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值