C语言解决快速幂的问题

  • Post author:
  • Post category:其他


本博文源于C语言求解快速幂的问题,快速幂是一种基于二分法的思想,常称为二分幂,快速幂基于以上事实:

  1. 如果b是奇数,那么有



    a

    b

    =

    a

    a

    b

    1

    a^b=a*a^{b-1}







    a










    b











    =








    a














    a











    b





    1












  2. 如果b是偶数,那么有



    a

    b

    =

    a

    b

    /

    2

    a

    b

    /

    2

    a^b=a^{b/2}*a^{b/2}







    a










    b











    =









    a











    b


    /


    2






















    a











    b


    /


    2












举个例子,如果需要求



2

10

2^{10}







2











1


0












  1. 对于



    2

    10

    2^{10}







    2











    1


    0













    来说,由于幂次10为偶数,因此需要先求



    2

    5

    2^{5}







    2











    5













    ,然后有



    2

    10

    2^{10}







    2











    1


    0













    =



    2

    5

    2

    5

    2^{5}*2^{5}







    2











    5






















    2











    5












  2. 对于



    2

    5

    2^{5}







    2











    5













    来说,由于幂次5为偶数,因此需要先求



    2

    4

    2^{4}







    2











    4













    ,然后有



    2

    5

    2^{5}







    2











    5













    =



    2

    2

    4

    2*2^{4}






    2














    2











    4












  3. 对于



    2

    4

    2^{4}







    2











    4













    来说,由于幂次4为偶数,因此需要先求



    2

    2

    2^{2}







    2











    2













    ,然后有



    2

    4

    2^{4}







    2











    4













    =



    2

    2

    2

    2

    2^{2}*2^{2}







    2











    2






















    2











    2












  4. 对于



    2

    2

    2^{2}







    2











    2













    来说,由于幂次2为偶数,因此需要先求



    2

    1

    2^{1}







    2











    1













    ,然后有



    2

    2

    2^{2}







    2











    2













    =



    2

    1

    2

    1

    2^{1}*2^{1}







    2











    1






















    2











    1












  5. 对于



    2

    1

    2^{1}







    2











    1













    来说,由于幂次1为偶数,因此需要先求



    2

    0

    2^{0}







    2











    0













    ,然后有



    2

    1

    2^{1}







    2











    1













    =



    2

    2

    0

    2*2^{0}






    2














    2











    0















  6. 2

    0

    2^{0}







    2











    0













    =1,然后从下往上依次回退计算即可。

#include<stdio.h>
typedef long long LL;
LL binaryPow(LL a,LL b,LL m){
    if(b==0) return 1;//如果b为0,那么a^0 = 1
    //b为奇数,转化为b-1
    if(b%2==1) return a* binaryPow(a,b-1,m)%m;
    else{
        //b偶数,转化为b/2
        LL mul = binaryPow(a,b/2,m);
        return mul * mul % m;

    }
}
int main()
{
    LL res = binaryPow(2,3,3);
    printf("%ld",res);
    return 0;

}

在这里插入图片描述

也可以将上面的进行位运算,代码就变成这样了。

LL binaryPow(LL a,LL b,LL m){
    LL ans = 1;
    while(b>0){
        if(b&1){
            //如果b的二进制末尾为1,(也可以写成if(b%2))
            ans = ans * a % m;//令ans累计上a
        }
        a = a*a%m;//令a平方
        b>>=1;//将b的二进制右移1位,即b=b>>1或b=b/2;
    }
    return ans;
}



版权声明:本文为m0_37149062原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。