问题描述:
输入a,b,其中a和b的范围是【2,999999999】,求出a的b次幂的最后3位。
PS:
如果最后三位是001,那么输出1就可以了。
问题分析:
这个问题的实际上是求a的b次幂mod 1000的结果,把这个问题一般化,实际上是a的b次幂mod n的结果。
(X*Y)%Z=((X%Z)*(Y%Z))%Z
根据蒙格马利快速幂模算法,我们可以方便求解,下面举个例子。
2^7:2*2*2*2*2*2*2
两两分开:(2*2) * (2*2) * (2*2) * 2
如果用2*2来计算,那么指数就可以除以2了,不过剩了一个,稍后再单独乘上它。
再次两两分开,指数除以2: ((2*2) * (2*2)) * (2*2) * 2
实际上最后一个括号里的2 * 2是这回又剩下的,那么,稍后再单独乘上它
现在指数已经为1了,可以计算最终结果了:16 * 4 * 2 = 128
把这个积模分解公式公式和上面的求模等式进行结合,就可以得到得到蒙格马利快速幂模算法。
参考代码:
#include <stdio.h>
unsigned Montgomery(unsigned a,unsigned b,unsigned n)
{
unsigned ans = 1;
a %= n;
while (b > 1)
{
if (b & 1)
ans = (ans * a) % n;
a = (a * a) % n;
b >>= 1;
}
return (ans * a) % n;
}
int main()
{
printf("%u\n", Montgomery(2, 10000000, 1000));
return 0;
}
运行结果: