JOJ1600 Big Mod

一直对那些ACM的神牛们从心底里有膜拜知情,总会对自己有些鄙视啊,好多数学方面的知识真的不是一般的匮乏,就唠叨到这里吧,

1600 : Big Mod


Result TIME Limit MEMORY Limit Run Times AC Times JUDGE
3s 8192K 1725 324 Standard

Calculate

 

 

for large values of B , P , and M using an efficient algorithm. (That's right, this problem has a time dependency !!!.)

Input

Three integer values (in the order B , P , M ) will be read one number per line. B and P are integers in the range 0 to 2147483647 inclusive. M is an integer in the range 1 to 46340 inclusive.

Output

The result of the computation. A single integer.

Sample Input

 

3
18132
17

17
1765
3

2374859
3029382
36123

Sample Output

 

13
2
13195
思路:这就是幂取模算法。

利用一个很基础的数论公式(a*b)%m=(a%m)*(b%m)%m=((a%m)*b%m)和一个指数运算法则a^(b+c)=a^b*a^c;

对于(a^p)%m;

我们可以把p写成二进制形式b0,b1,b2,b3.....bn(从低位到高位);

其对应的二进制位上相应权值为2^0,2^1,2^2,2^3,2^4,2^5,2^6,2^7,2^8.....(设为w0,w1,w2,w3,w4.....wn...).

可以想到a^p=a^(b0*w0+b1*w1+b2*w2+bn*wn)=a^(b0*w0)*a^(b1*w1)*a^(b2*w2)*......*a^(bn*wn);

我们设一个变量res来保存运算结果,并初始化为1。

现在我们从左向右遍历b的二进制序列。


如果相应的位数上对应值为1则进行:

res=(res*a)%m;  //别忘了%m,这里a相当于各位对应的权值,这样做并不会影响最终的结果,因为我们有前面提到的公式。

不论相应位上是不是1都要对a进行。

a=(a*a)%m;  //这样做是为了使a等于上各个二进制位对应的权值。同样别忘了%m操作。

当遍历完二进制序列后,输出res即可。

注意一点就是当b=0并且m=1的时候,要特殊考虑(当然也可以不用),完全取决于你的程序具体实现,与算法无关。

忘记说了这个算法复杂度是O(log2(n))。

下面给出上面这道题的AC代码,不知道0.03s的牛们是怎么做的。还要感谢飞哥对我的算法讲解。
刚刚知道了0.03s的牛们是怎么做的了,原来输入输出全是标准C,这一次我真得领教了怎么两种语言输入处理速度的差别了,不能小看测试数据的量啊。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值