用数论的知识解决模幂运算
在数学上,如果数A与数B对M取模后得到的值相等,即A%M=B%M,则称A与B是关于模M同余,记为A≡B。
此外对于同余运算有如下定理:(自己推导的话也可以轻易得证)
(1)若A≡B,则存在常数D,使得A+D≡B+D ;
(2)若A≡B,则存在常数D,使得A*D≡B*D ;
(3)若A≡B,则存在常数n,使得A^n≡B^n ;
基于此原理,对于模幂运算,即A^n%m的运算可以,通过A^n≡B^n(前提A≡B)的形式来化简,辅以定理(1)和(2),可以实现以较短的时间进行求解。
程序如下:
1 /*=========================================== 2 * 3 * 函 数 名:ModCal 4 * 5 * 参 数: 6 * int digit:底数 7 * int n :指数 8 * int m :模数 9 * 10 * 功能描述:运算数论原理解决模幂运算 11 * 12 * 返 回 值:返回模幂运算的结果 13 * 14 * 抛出异常: 15 * 16 * 作者:crazyhf 2012/05/04 17 * 18 ============================================*/ 19 20 int ModCal( int digit, int n, int m ) 21 { 22 int muldigit, i ; 23 digit %= m ; 24 25 if ( !n || digit == 1 ) return 1 ; 26 27 for( i = 1, muldigit = digit; 28 i < n && muldigit < m; 29 muldigit *= digit, i++ ) ; 30 31 if( i == n ) return muldigit %= m ; 32 33 return ModCal( muldigit, n / i, m ) * ModCal( digit, n % i, m ) % m ; 34 }
模幂运算功能的测试代码如下:
# include <iostream> using std::cin ; using std::cout ; using std::endl ; int main( int argc, char **argv ) { while( 1 ) { int digit, n, m ; if( cin >> digit >> n >> m ) { cout << ModCal( digit, n, m ) << endl ; } } return 0 ; }