快速幂(取模)、快速积(取模)运算

快速幂运算

幂运算又叫指数运算,既是a的n次累乘。
快速幂运算中我们用到了蒙哥马利幂算法。将时间复杂度从O(n)降到O(logN)。
具体原理参考:
二进制拆分
快速幂-反复平方法
代码如下:

long long qpow (long long a,long long b){
 long long result=1;
 while (b){
     if (b&1)
         result*=a;
     b>>=1;
     a=a*a;
 }
 return result;
 }

取模取余的区别

下面以整型 a 和 b 两个变量举例,在我们常说的取余运算中,其算法会分成以下的两个步骤:

  1. 求整数商:c = a / b
  2. 求余数:r = a - c * b

取模与取余不同在于第一步,求余在整除的时候是往 0 方向逼近,而取模是往负无穷方向逼急。这样就造成了在对负数进行取模运算的差异。所以在计算 -7 % 4 的时候,求余运算的结果是 -3,而取模运算是 1。

/// 第一步:求整数商
// 求余运算
-7 / 4 = -1 (逼近 0 )

// 求模运算
-7 / 4 = -2 (逼近负无穷)

/// 第二步:
// 求余运算
-7 - (-1) * 4 = -7 + 4 = -3

// 求模运算
-7 - (-2) * 4 = -7 + 8 = 1

当然,逼近方向其实不影响其他的运算规律,因为任意的 a % b,对于给定的 a 和 b ,计算结果一定是一个确定的值。所以我们只需了解这两种计算的区别就可以。

不同的编程语言对于 % 的处理是不一样的。Python中的%运算是按求模运算,C/C++/Java是按求余运算。

快速幂取模运算

(a * b) mod n =[(a mod n) * (b mod n)] mod n

将上面公式与快速幂运算算法结合起来。
代码:

long long qpowmod (long long a,long long b,long long mod){
  long long result=1;
  while (b){
      if (b&1)
          result=(result*a)%mod;
      b>>=1;
      a=(a*a)%mod;
  }
  return (result);
  } 

快速积运算

求两个数的乘积。
将其中一个数由十进制转换为二进制。再运用分配律。
例如:
a * 15 = a * (1111)2 =a * 23 * 1 + a * 22 * 1 + a * 21 * 1 + a * 20 * 1
代码:

long long qmul(long long a,long long b) {
 long long ans=0;
 while(b){
     if(b&1) 
         ans+=a;        
     a=a*2;
     b>>=1; 
 }
 return ans;
}

快速积取模

(a * b) mod n =[(a mod n) * (b mod n)] mod n

(a + b) mod n =[(a mod n) + (b mod n)] mod n
long long qmulmod(long long a,long long b,long long mod) {
  long long ans=0;
  while(b){
      if(b&1) 
          ans=(ans+a)%mod;        
      a=(a*2)%mod;
      b>>=1; 
  }
  return ans%mod;
}

参考

快速幂(取模)、快速积(取模)算法解析
快速幂取模算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值