幂运算取模

快速幂也就是我们求解 ab mod k a b   m o d   k 这种类型的式子会用

1. 解法一 暴力求解

暴力求解也就是类似下面代码

for(int i = 0;i<b;i++)
{
a *=a;
}
a%=k;

这种方法是不可取的
例如:
21003% 3 2 1003 %   3 是非常消耗我们的计算资源的。
- - 缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增大,非常的占用我们的计算资源(主要是时间,还有空间)
- - 缺点2:我们计算的中间过程数字大的恐怖,我们现有的计算机是没有办法记录这么长的数据的,所以说我们必须要想一个更加高效的方法来解决这个问题

2. 解法二 引入 取模运算

在引入快速幂之前我们先了解一下取模运算

(ab)% k==(a% k)(b% k)% k ( a ∗ b ) %   k == ( a %   k ) ( b %   k ) %   k
证明
x=am+b x = a ∗ m + b
y=cm+d y = c ∗ m + d
xy=(am+b)(cm+d)=(acm)2+(ad+bc)m+bd=bd(modm) x y = ( a ∗ m + b ) ( c ∗ m + d ) = ( a ∗ c ∗ m ) 2 + ( a ∗ d + b ∗ c ) ∗ m + b ∗ d = b ∗ d ( m o d m )
x=b mod my=d mod m x = b   m o d   m y = d   m o d   m

得解 (ab)% k==(a% k)(b% k)% k ( a ∗ b ) %   k == ( a %   k ) ( b %   k ) %   k

然后 我们的式子就可以变成

(2 mod 3)1003 mod 3 ( 2   m o d   3 ) 1003   m o d   3

这时我们的代码可以变成

            int i = (a%k);  //i代表我们每次运算时要乘的数字
         for(;b>1;b--){
             a%=k;  //a取模
             a=a*i;
         }
         a%=k;

但这样还不够,当我们b足够大时,我们要进行b次实验。这样还是会浪费许多时间

3. 解法三 引入幂运算的取模运算

前面引入了取模运算在这里我们再来讲一下 一种新的幂运算
ab=(a2)b2 a b = ( a 2 ) b 2
由这个公式可以把我们的运算变成了 b2 b 2 次。
比如 21000000072100000089mod 45987 2100000007 2100000089 m o d   45987

这样用上面的方式运算时肯定要超时的。 我们就可以用这个
步骤如下:
①先判断b能否被整除
因为我们的的最终结果将在 B2==1 B 2 == 1 时出结果
若不能整除 我们的 res=ares%k r e s = a ∗ r e s % k 一方面使我们的b始终为偶数,一方面也记录了我们的答案
②计算 a2%k a 2 % k
代码如下

 long res = 1;
         for(;b>1;b/=2){
            if(b/2==1)
            {
                res = res*a%k; 
            }
            a=(a*a)%k;
         }

例题:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值