整数快速幂讲解

我们先来看,要求一个整数的 n 次幂,普通的方法的话,是不是需要乘以 n 次这个数?这里如果幂次非常大的话,肯定会非常耗时,所以有超时的危险,也是有很多卡时间的题的,所以这里就牵涉到一个快速幂的思想:

所谓快速幂,就是快速求幂次。我们知道,所有的数字,都可以用二进制来表示对吧,比如 21 ,它的二进制数字为 10101 ,也就是他可以分成 21 = 1 + 4 + 16 ,也就是21=2^{0}+2^{2}+2^{4},也就是二进制数从最后一位,权值为 1,到最高位权值为 16,可以看到如下情况:21=2^{0}*1+2^{1}*0+2^{2}*1+2^{3}*0+2^{4}*1,所以这个数的二进制数的各个位上的数字,如果为 1,就加上这个位的权值,如果不为 1,就不加。

然后介绍一下 ‘&’ 这个符号的意义,这个符号就是将对应二进制位对齐,然后同一位上都为 1 则结果为 true ,否则为 false 比如 10101 & 1 = 1 , 10100 & 1 = 0。‘>>’这个符号的意义是将整个二进制数字右移,也可以理解为除以 2 ,就是将最后一位剔除的意思,比如 10101 >> 1 = 1010

所以我们可以用 & 来取出最后一位的数字,然后用 >> 右移来一步一步进行提取,然后如果最后一位上的数字为 1,则为真,否则为假。而我们一般分解的数字是幂次的数字,也就是如果要求x^{21}我们分解的是 21,然后权值就会变成x^{0}x^{1}x^{2}x^{3}x^{4},所以如果判断为真(最后一位为1)则乘以对应的权值,如果判断为假,则不乘。

注意:不管当前位是不是 1,都要权值都要自乘,因为权值要一直改变。

所以当我们需要求2^{21}的时候,我们将它分为2^{21}=res*2^{1}*2^{4}*2^{16},此处 res = 1,所以只需要计算 3 + 4(自乘) 次乘法,而不是 21 次。

普通版代码:

/**普通算法*/
#define ll long long int
ll power1(ll a, ll b) ///a为底数,b为幂次
{
    ll res = 1;
    for(ll i = 1; i <= b; i++) ///乘以b次底数
    {
        res *= a;
    }
    return  res;
}

快速幂算法:

/**快速幂优化后算法*/
#define ll long long int
ll power2(ll a, ll b) ///a为底数,b为幂次
{
    ll res = 1; ///res为最终结果
    a %= c; ///a为需要取余的数字
    while (b)
    {
        if (b & 1) ///判断最后一位
            res = res * a;
        a = a * a; ///a自乘
        b >>= 1; ///b应当右移一位
    }
    return res;
}

优化后算法时间复杂度可以从O(n)变成O(log_{2}n),当数据大的时候,优化其实是特别明显的。

 

OVER!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值