【原】模幂运算(Modular Exponentiation)算法

模幂运算常常作为一些算法的中间求解步骤,算法的思路十分巧妙并且高效。模幂运算的描述如下:

    已知b, e, m, 求c。形如:

    clip_image002[5]

    其中,b<m (若b>m,可转换b为b%=m)

 

 

算法一:最显而易见的办法就是先求幂,再取模。例如

clip_image002[9],得到 c = 445。 clip_image002[11]

注意到b=4为1位,e=13为2位,m=497为3位,c=445为3位,但是 clip_image002[15] 为8位。这很可能造成溢出,或者因为大整数运算而缓慢。

可以采用快速求幂法求得 clip_image002,时间复杂度为 O(loge)

   1: int Power(int b, int e)
   2: {
   3:     if (0 == b || 1 == b || 0 == e)
   4:         return 1;
   5:     if (1 == e)
   6:         return b;
   7:     int n = e>>1;
   8:     int tmp = Power(b, n);
   9:     if (0 == (e&1))
  10:         return tmp*tmp;
  11:     else
  12:         return tmp*tmp*b;
  13: }

 

 

算法二:称为Right to left binary method

这里利用了等式:

clip_image002[17]

同时将e表示作二进制表示形式:

clip_image002[19]

所以 clip_image002[21] 可以表示为:

clip_image002[23]

因此所需求得的结果c为:

clip_image002[25]

算法实现如下:

   1: typedef __int64 BigInt;
   2:  
   3: //modular exponentiation
   4: BigInt modexp(BigInt b,BigInt e,BigInt m)
   5: {
   6:     b%=m;
   7:     BigInt result=1;
   8:     while(e>0)
   9:     {
  10:         if( e&1 == 1 )
  11:             result = (result*b)%m;  
  12:         // multiply in this bit's contribution while using modulus to keep result small
  13:         // move to the next bit of the exponent, square (and mod) the base accordingly
  14:         e >>= 1;  
  15:         b = (b*b)%m;
  16:     }
  17:     return result;
  18: }

算法时间复杂度为O(loge),若算上大整数相乘则总复杂度为O(loge*logm*logm)。

该算法最大优点在于空间要求同比于b,e,m的空间,不会造成溢出或者更多的空间占用。

因此在时间和空间上都高效。

posted @ 2011-01-30 13:06  Allen Sun  阅读(4178)  评论(0编辑  收藏