3.2.10取余运算(递归与分治)

目录

问题描述

输入

输出

输入样例

输出样例

算法分析

算法1: 

参考书籍


问题描述

输入三个正整数a,p,k,求a^{p}%k的值。

输入

输入有多组测试例

对每组测试例,有三个正整数a,p,k(0<a,p,k\times k<2^{32}).

输出

对每组测试例输出一行,是a^{p}%k的值。

输入样例

2 10 9

3 18132 17

输出样例

7

13

算法分析

 由于数据的规模很大,如果直接计算,不仅需要采用高精度,而且时间复杂度很大。例如,10^{25}%7= 3,但10^{25}超出了整数型的表示范围,不能直接计算。

模运算有如下运算规则:

(1)(a\times b)%n=(a%n\times b%n)%n

(2)a^{b}%n=((a%n)^{b})%n

根据公式(2),10^{25}%7=(10%7)^{25}%7=3^{25}%7.显著降低了a的值。

根据公式(1),3^{25}%7=(3\times 3^{12}\times 3^{12})%7=(3\times3 ^{12}%7\times 3^{12}%7)%7.显著降低了p的值。

因此,得到如下递推公式:

a^{p}%k\left\{\begin{matrix} a%k-----(p=1)\\ (a\times a^{p-1}%k)%k--(p-is-odd)\\ ((a\times a)%k)^{p/2}%k--(p-is-even)\\ \end{matrix}\right.

该递推公式体现了分治策略的应用,将一个大的指数p逐渐减小,同时对运算过程的中间结果不断进行模运算,降低中间结果的数字大小,避免了使用高精度运算。

利用递推公式实现取余运算,如算法1所示。

算法1: 

//计算a^p%k的值
//为了防止运算过程中的溢出,采用64位整数,在C++环境中是long long
int mod(__int64 a,__int64 p,__int64 k)
{
     if(p == 1) return a % k;
     if(p % 2) return mod(a%k , p-1, k);     //p是奇数
     else return mod((a*a)%k,p/2,k);         //p是偶数
}
//主函数main()中的数据读取与调用
unsigned a,p,k;
while (scanf("%u %u %u",&a,&p,&k)!=EOF)
    printf("%d\n",mod(a,p,k));

参考书籍

 算法设计与分析 -----以ACM大学生程序设计竞赛在线题库为例     ------清华大学出版

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值