码迷,mamicode.com
首页 > 其他好文 > 详细

快速幂(Quick pow)

时间:2020-02-23 15:00:27      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:ant   important   五步   pow   大致   推导   long   进制   type   

Quick pow is very important and basics.

法一(递归法):

先举个栗子:

求2 ^10?

我们将它分为下面五步:

  1. 2^10 = 2^5 * 2^5
  2. 2^5 = 2 * 2^4
  3. 2^4 = 2^2 * 2^2
  4. 2^2 = 2^1 * 2^1
  5. 2^1 = 2 * 2^0

总的来说就是:

1)当b是奇数时,那么有 a^b = a * a^*(b-1)

2)当b是偶数时,那么有 a^b = a^(b/2) * a^(b/2)

于是,我们可以写出如下快速幂递归代码:

typedef long long ll;
ll quickPow(ll a, ll b, ll m)
{
    if(b == 0) return 1;
    else if(b&1) return a*quickPow(a,b-1,m)%m;
    else
    {
        ll num = quickPow(a,b/2,m)%m; //优化 
        return num*num%m;// or直接写成:return binaryPow(a,b/2,m)%m*binaryPow(a,b/2,m)%m%m
    }    
}

法二:(迭代法)

对于 a ^ b来说,若果把 b 写成2 进制,那么b 就可以写成若干二次幂之和,如13 的二进制 1101,于是3 号位 、2号位、0号位就都是1,那么就可以得到13 = 2^3 + 2^2 + 2^0 = 8 + 4 + 1。所以a ^13 = a^8 * a^4 * a^1。

通过同样的推导,我们可以把任意的a^b 表示成 a^(2^k)……、a^8、a^4、a^2、a^1中若干的乘积。若果二进制的i号位为1.那么想中的a^(2^i)就被选中。于是可以得到计算a^b的大致思路:令i 从0到k枚举b的二进制的每一位,如果为1 那就累计a^(2^i)。

注意 a^(2^k)……、a^8、a^4、a^2、a^1前一项总是等于后一项的平方。具体步骤。

(1)初始令ans = 1,用来存放累积的结果。

(2)判断b的二进制末尾是否为1,(及判断 b&1 是否为 1),也可以理解为判断b 是否为奇数。如果是的话,令ans乘上a的值。

(3)令a平方,并使b右移一位,(也可以理解为,b/2)

(4)只要b 大于0,就返回(2)。

typedef long long ll
ll binaryPow(ll a, ll b, ll m){
    ll ans = 1;
    while(b > 0)
   {
if(b & 1)
     { ans
= ans * a % m;
     } a
= a * a % m; b >> = 1; } return ans; }

 

快速幂(Quick pow)

标签:ant   important   五步   pow   大致   推导   long   进制   type   

原文地址:https://www.cnblogs.com/Cnxz/p/12349493.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!