快速幂

快速幂

ll fast_power(ll x, ll y)
{
    ll base=x,ans=1;
    while(y)
    {
        if(y&1)
        {
            ans*=base;
        }
        base*=base;
        y>>=1;
    }
    return ans;
}

快速幂的思想就是将指数换为二进制来做。
比如说 2^ 11 :11=2^ 3+2^ 1+2^ 0=8+2+1 用二进制来表示就是(1011)
2^ 11=2^ 8+2^ 1+2^0
于是:
base就是从最低位开始二进制位上的次幂运算完成后的结果,指数的二进制位若为1,结果就乘以相应的次幂运算结果

以下是最最开始还没有接触位运算的时候的极其粗略的见解,有的地方很怪异,有选择地看,或者不看……

这个理解起来其实没啥方法,就是实际模拟一下,然后就会豁然开朗哈哈哈。

先来理解一下:
比如说a的b次方
把b转换成二进制数。
例如
11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
因此,我们将a¹¹转化为算a^ (2³×1 + 2²×0 + 2¹×1 + 2º×1),
即(a^ (2º×1)) (a^ (2¹×1)) (a^ (2²×0)) (a^ (2³×1))
即 (a^ 8) (a^ 2) (a^1)

b & 1:
取b二进制的最低位,判断和1是否相同,相同返回1,否则返回0
(注:因为1的二进制是000001,所以如果b的二进制最低位和1的相同,即返回值为1;相反,如果b的二进制最低位和1不同,即返回值为0。由上面11的例子可知,当b&1返回为0的时候,结果要乘上base,否则,不乘。但是base* =base是一直进行的)
b>>1:
把b的二进制右移一位,即去掉其二进制位的最低位

还是以a的11次方为例:11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1(1011)
pow(a,b=11)
首先结果r=1,base=a;
11的二进制最低位是1,1&1=0,所以r=r* base=a;
此时base=base* base=a^2;
b>>,即1&1=0,所以还是r=r* base=a^3;
此时base=base* base=a^4;
b>>,即0&1=1,所以r=a^3不变;
此时base=base* base=a^8;
b>>,即1&1=0,所以r=r* base=a^11;
至此,b已经为0,循环结束。
所以明白了没。
其实我也不是很懂,但是大概就是这样理解的,以后要是哪天有大神指点迷津,再重新发一个。呜呜呜,好弱…

位运算

int pow(int a,int b)
{
    int r=1,base=a;
    while(b)
    {
        if(b&1)
            r*=base;
        base*=base;
        b>>=1;
    }
    return r;
}

这里再说一下为什么if的判断条件是b%2
因为奇数的话,二进制最低位肯定是1,偶数是0,这个很明显。
所以呢,跟b&1是一样的,如果b&1返回了0,说明b的二进制最低位是0,即b是偶数,反之,b是奇数,所以就很显然了,是b取模2;

一般

int pow(int a,int b)
{
    int r=1,base=a;
    while(b!=0)
    {
        if(b%2)
            r*=base;
        base*=base;
        b/=2;
    }
    return r;
}

这个递归很好玩哈哈哈,但是我还是比较才疏学浅,只会手算。
还是以pow(a,b=11)为例嘛,嘿嘿嘿。
首先pow(a,11)
temp=pow(a,5),返回a* pow(a,5)^2
再就pow(a,5)
temp=pow(a,2),返回a* pow(a,2)^2
再就pow(a,2)
temp=pow(a,1)=a,返回pow(a,1)^2

所以倒着看回去,
pow(a,1)=a;
pow(a,2)=pow(a,1) ^2 = a ^2;
pow(a,5)=a* pow(a,2) ^2 =a* (a ^2 ) ^2=a ^5;
pow(a,11)=a* pow(a,5) ^ 2=a* (a ^5) ^2=a ^ 11;

the end;

递归

int pow(int a,int b)
{
    if(b==1)
        return a;
    int temp=pow(a,b/2);
    return (b%2==0 ? 1 : a) * (temp * temp);
}

SUMMARY
其实,无论是哪一种来说,这个快速幂的根本其实就是
a^b=(a ^2) ^(b/2) (b是偶数时)
a^b=a * (a ^2) ^(b/2) (b是奇数时)

呜呜呜,但是我还是好弱,所以说的有点混,估计也就我自己能看懂我自己写的啥吧,呜呜呜……

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值