【暖*墟】 #快速幂# 快速幂的实现与运用

73 篇文章 0 订阅
7 篇文章 0 订阅

快速幂引入

while(b > 0){
    if(b & 1)
        ans *= base;

/*询问此时b(二进制)的最后一位是 1 吗? 是的。
这代表 a^{11} = a^8 × a^2 × a^1 中的“ × a^1 ”存在。
所以 ans∗=base。注意,base的值是会流动的。 */


/*关于 b & 1:“按位与”。
x & y 是二进制 x 和 y 的每一位分别进行“与运算”的结果。
与运算,即两者都为 1 时才会返回 1,否则返回 0。
          二进制
b     =    1011
1     =    0001
b&1   =    0001
因为 1(二进制)的前面几位全部都是 0,所以不会影响前面。
当 b 二进制最后一位是 1 时,b & 1 才会返回 1。*/

    base *= base; //然后 base 倍增,通过自乘一次,使自己变成 a^2 。


    b >>= 1; //进行之后,b=(101)2

//把(二进制下的)自己每一位都往右移动了。原来的最后第二位,变成了最后第一位。

}

【代码综合实现】

一行代码:

ll power(ll a,ll b){ //快速幂
    ll anss=1; while(b) anss=anss*(b&1?a:1)%p,a=a*a%p,b>>=1; return anss;
}

带注解代码:

ll power(ll a,ll b,ll m){ //求a的b次方%m
    ll ans=1; //ans为答案
    while(b>0){ //b是不断右移的二进制数
        if(b&1) //&是位运算,b&1表示b在二进制下最后一位是不是1,如果是:
            ans=(ll)ans*a%m; //把ans乘上对应的a^(2^i)
        a=(ll)a*a%m; //a自乘,由a^(2^i)变成a^(2^(i+1))
        b>>=1; //位运算,b右移一位
    }
    return ans;
}

取余运算

快速幂经常要结合取余运算。这里也讲一点。

取余运算有一些好用的性质,包括:

while(b > 0){
    if(b & 1){
        ans *= base;
        ans %= m; //边乘边余
    }
    base *= base;
    base %= m;  //边乘边余
    b >>= 1;
}

 

                                               ——时间划过风的轨迹,那个少年,还在等你。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值