我们给出了3个数字:a,s和b,每个都在1到1000000之间变化。我们需要找到pow(a,s)%b。显然,我们不能使用简单的pow函数,因为我们无法生成大数,例如1000000 1000000 。这是问题的解决方案:
sol=1
for(int i=0;i<s;i++)
{
sol = sol * a;
sol = sol % b;
}
print sol
我不明白这个算法。有人可以向我解释一下吗?
P.S。我在哪里可以找到更多解决非平凡数学问题的算法,例如这个? 干杯!
答案 0 :(得分:7)
首先,您编写的算法根本没有优化,因为它在s中是线性的,而您可以轻松地编写一个日志,因为您可以阅读here。
那就是说,没有太多要解释的:你只需要知道
a*b mod N = ((a mod N) * ( b mod N)) mod N
那个
a^s = a*a*...*a s times
并且紧接着你的算法以天真的方式计算结果。
答案 1 :(得分:4)
a s mod b =(a•a s-1 )mod b =(a mod b)•(a s-1 mod b)mod b = ...
正如您所看到的,第一步是微不足道的,而第二步是模数的已知属性。所以你可以迭代并找到一个 s mod b。
正如其他提到的,你可以做得更好。对于其他方法,您可以转到Wikipedia。但我将解释这个算法背后的想法:用二进制代表数字s
,这样你就可以用以下方式编写s
:
s =Σ(2 i •b i )其中每个b i 为0或1。
所以: s mod b = a Σ(2 i •b i ) mod b,所以你可以在LSB = 1时进行乘法,然后向右移动指数......