用数论的知识解决模幂运算

 

在数学上,如果数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 ;
}

 

posted @ 2012-05-04 21:13  crazylhf  阅读(333)  评论(0编辑  收藏  举报