【问题】:模取幂运算 计算a^b mod c
【思路】:
b % 2 = 0 (a ^ b) % mod =|
(((a ^ (b / 2 )) % mod) ^ 2 * a) % mod b % 2 = 1
【即】:根据上面的式子,可以直接用递归,也就是从顶向下来计算,或者我们自底而上来计算.
从上面的式子中我们注意到,我们是按b%2的情况来递归地计算a^b%mod的,于是,在整个递归过程中,我们是按b的二进制展开形式来计算的,如果我们实现得到了b的二进制形式,我们就可以自底而上的计算a^b%mod了.
【解决方法】:/****************************************************/
// 模取幂运算 计算a^b mod c
// 利用公式
// (a*b)mod(c) = ((a mod c )*b)mod c
/****************************************************/
int a_b_Mod_c(int a, int b, int c)
{//前提 a b c 都是正数
int digit[32];
int i, k, resualt = 1;
i = 0;
while(b)//把b化成2进制
{
digit[i++] = b%2;
b >>= 1;
}
//计算(a^b) mod c
for(k = i-1; k >= 0; k--)
{
resualt = (resualt * resualt) % c;
if(digit[k] == 1)
{
resualt = (resualt * a) % c;
}
}
return resualt;
}
【延伸】:
三进制的:int a_b_Mod_c(int a, int b, int c)
{//前提 a b c 都是正数
int digit[32];
int i, k, resualt = 1;
i = 0;
while(b)//把b化成3进制
{
digit[i++] = b%3;
b /=3 ;
}
//计算(a^b) mod c
for(k = i-1; k >= 0; k--) = (resualt * resualt * resualt) % c; //因为基数是3,所以要3个resualt相乘意
if(digit[k] == 1)
{
resualt = (resualt * a) % c; //因为3进制会出现0,1,2,当为1时就乘一个a
}
else if(digit[k]==2)
{
resualt = (resualt *a*a) % c;//当为2时乘两个a
}
}
return resualt;
}
{resualt
四进制的:
int a_b_Mod_c(int a, int b, int c)
{//前提 a b c 都是正数
int digit[32];
int i, k, resualt = 1;
i = 0;
while(b)//把b化成4进制
{
digit[i++] = b%4;
b /=4;
}
//计算(a^b) mod c
for(k = i-1; k >= 0; k--)
{
resualt = (resualt * resualt*resualt*resualt) % c; //基数是4,4个resualt
if(digit[k] == 1)
{
resualt = (resualt * a) % c; //会出现0,1,2,3 如上
}
if(digit[k]==2)
resualt = (resualt * a *a) % c; //为2时 如上
if(digit[k]==3)
resualt = (resualt * a * a * a) % c; //为3时 如上
}
return resualt;
}