快速幂取模

来源:互联网 发布:手机pdf阅读器 知乎 编辑:程序博客网 时间:2024/05/22 10:35


如何快速地求A^B,特别是当A,B都很大的时候.结果取A^BmodC

 

菜鸟解法:

Result=pow(A,B)modC.

超过int范围,挂掉.

 

菜鸟想了想,每次乘一个A,modC :

Result=1;

While(B--)

{

       Result*=A;

       Result%=C;

}

超时,挂掉.

 

超时~~菜鸟又想到了二分法

A^B=A^((B/2)*2)=(A^(B/2))^2;

 

继续思考,B并不正好都是2^M.不过B可以拆分为多个2^M.如:

25=2^4+2^3+2^0;

B用二进制表示为(b30b29b28…b0).

 

问题转化为:

A^( b30b29b28…b0)=A^(b30*2^30)*A^(b29*2^29)*….A^(b0*2^0);            (1)

并且A^(2^i)=A^(2^(i-1)*2)=[A^(2^(i-1))]^2.

用f(i)表示多项式(1)的第i项,那么有如下递推公式:

F(i)=f(i-1)^2.

 

大功告成,用递推求每一项,时间复杂度为O(1).开始编码:

int f(int a,int b,int c){   int pos=1;   int temp=a;   int sum=1;   for(int i=0;i<31;i++)    {           if(b&pos)           sum=(sum*temp)%c;           pos=pos<<1;           temp=temp*temp%c;    }   return sum;}