快速幂算法

快速幂算法

一、简单介绍

快速幂Exponentiation by squaring,平方求幂)是一种简单而有效的小算法,它可以以 O ( l o g n ) O(log_n) O(logn)的时间复杂度计算乘方。快速幂不仅本身非常常见,而且后续很多算法也都会用到快速幂。

二、计算 7 10 7^{10} 710

​ 让我们先来思考一个问题:7的10次方,怎样算比较快?

​ 最朴素的想法,77=49,497=343,… 一步一步算,共进行了9次乘法。这样算无疑太慢了,尤其对计算机的CPU而言,每次运算只乘上一个个位数,无疑太屈才了。这时我们想到,也许可以拆分问题。

​ 我们换一个角度来引入快速幂。还是7的10次方,但这次,我们把10写成二进制的形式,也就是 1010。于是这个问题就变成了求7的二进制(1010)次幂。这样就只需要计算4次,相比于9次,大大提升了效率。

做法:计算 7 10 7^{10} 710,也就是计算 7 1010 = 7 ( 1000 ) 2 × 7 ( 10 ) 2 = 1 7 ( 8 ) 10 × 7 ( 2 ) 10 7^{1010} = 7^{(1000)_2} \times 7^{(10)_2} = 17^{(8)_{10}} \times 7^{(2)_{10}} 71010=7(1000)2×7(10)2=17(8)10×7(2)10,那么只需要计算 7 ( 8 ) 10 × 7 ( 2 ) 10 7^{(8)_{10}} \times 7^{(2)_{10}} 7(8)10×7(2)10。更一般化,只需要计算 7 2 0 , 7 2 1 , 7 2 2 , . . . , 7 2 n 7^{2^{0}},7^{2^{1}},7^{2^{2}},...,7^{2^{n}} 720,721,722,...,72n

三、一般化

1、计算 a n a^n an的快速方法:

(1)将 n n n 转化成二进制形式,例如1011010

(2)转化后的形式为 a ( x k x k − 1 . . . x 2 x 1 x 0 ) 2 = a x k 0...00 × a 0 x k − 1 . . . 00 × a 00...10 × a 00...01 a^{(x_kx_{k-1}...x_2x_1x_0)_2} = a^{x_k0...00} \times a^{0x_{k-1}...00} \times a^{00...10} \times a^{00...01} a(xkxk1...x2x1x0)2=axk0...00×a0xk1...00×a00...10×a00...01.

(3) 需要计算的数值为 a 1 , a 2 , a 4 , a 8 , . . . . , a 2 n a^{1},a^{2},a^{4},a^{8},....,a^{2^{n}} a1,a2,a4,a8,....,a2n.

2、时间复杂度分析:

​ 一般求解 a n a^n an 时,需要计算n次。但是使用快速幂算法之后,将 n n n 表示成二进制只需要 O ( l o g n ) O(log_n) O(logn) 位数字,只需要计算 O ( l o g n ) O(log_n) O(logn)次。

四、代码

public static Long quickPow(Long a,Long n,Long p){
    //结果
    Long res = 1L;
    while (n != 0) {
        //判断 n 的二进制的最后一位是否为0
        if((n&1)!=0){
            //当n的二进制最后一位为1时,乘以当前的权重
            res = (res*a)%p;
        }
        //更新n,每次n向右移一位
        n = n >> 1;
        //更新每一位的权重
        a = (a*a)%p;
    }
    return res;
}

五、参考资料

[1] 基础算法—快速幂详解

[2] 快速幂算法

快速幂算法](https://blog.csdn.net/HouGOD/article/details/123847315)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值