【原】模幂运算(Modular Exponentiation)算法
模幂运算常常作为一些算法的中间求解步骤,算法的思路十分巧妙并且高效。模幂运算的描述如下:
已知b, e, m, 求c。形如:
其中,b<m (若b>m,可转换b为b%=m)
算法一:最显而易见的办法就是先求幂,再取模。例如
注意到b=4为1位,e=13为2位,m=497为3位,c=445为3位,但是 为8位。这很可能造成溢出,或者因为大整数运算而缓慢。
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
这里利用了等式:
同时将e表示作二进制表示形式:
因此所需求得的结果c为:
算法实现如下:
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的空间,不会造成溢出或者更多的空间占用。
因此在时间和空间上都高效。