慢速乘与快速幂

目录

 

慢速乘(防一次乘法就爆long long):

快速幂(加快次方速度):

混合用:


慢速乘(防一次乘法就爆long long):

有可能两个数相乘直接爆掉long long。化乘为加。a*b

任意数都可以拆分二进制,如果对应位是1,加上,否则右移。注意b二进制右移一位,a就要乘2。因为二进制每一位权值对应*2。

注意ans初始化为0,因为0加任何数都不变。

ll mul(ll a,ll b){//a*b   %p

       ll ans = 0;

       while(b){

              if(b%2 == 1)   ans = (ans+a)%p;

              b>>=1;

              a = (a+a)%p;

       }

       return ans;

}

快速幂(加快次方速度):

如果指数太大,for遍历时间复杂度O(n)。快速幂O(logn)。

a^p 如果p是偶数,就相当于(a^2)^(p/2)。如果p是奇数,就让p-1再转化。也就是拆分a^p=a^(p-1)*a。这时候把a乘到ans中去,再转化。

注意ans初始化为1,因为1乘任何数不变。

ll qpow(ll a,ll b){//a^b  %p

       ll ans = 1;

       while(b){

              if(b&1)   ans = ans*a;

              b >>= 1;

              a = a*a;

       }

       return ans;

}

混合用:

也就是当需要大数的乘法。p是1e9-1e14。这时候可能乘一下就爆long long.这时候就需要把快速幂的乘法转化为慢速乘。

ll mul(ll a,ll b){//a*b   %p

       ll ans = 0;

       while(b){

              if(b%2 == 1)   ans = (ans+a)%p;

              b>>=1;

              a = (a+a)%p;

       }

       return ans;

}

ll qpow(ll a,ll b){//a^b  %p

       ll ans = 1;

       while(b){

              if(b&1)   ans = mul(ans,a);

              b >>= 1;

              a = mul(a,a);

       }

       return ans;

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值