快速幂取余算法总结详解
废话不多说, 直接步入正题。
现在oj网站的题或者竞赛的题,如果a的b次幂且b很大,那么题中大多会让你把结果对一个数取余也就是求模,例如a^b%c这种,当然如果是考高精度的题除外。
接下来我将提供一种常规算法和两种竞赛中主流的快幂算法。
首先我们设题目要求为a^b mod c
常规算法
这里我就不多作解释,直接码代码了
int mod(int a, int b, int c){int i, ans = 1;for (i = 0; i < b; i++)ans = (ans * a) % c; //在这里对c取余是为了防止数据溢出return ans;
}
这个算法的时间复杂度为O(n),不是很高,但是一旦题目中b的取值很大且时间要求高的话,那么这个时间复杂度就危险了,接下来得靠我们的快幂算法来摆平。
快幂算法1
这里我们需要两个公式:
这两个公式都不难理解,自己可以验证一下,3^4 = 9^2。
有了这两个公式之后我们就可以考虑思路了。
我们就以b为偶数来举例。
a^b%c = ((a^2)^b/2)%c;
在这里我们假设b/2还是偶数,那么
((a^2)^b/2)%c = (((a^2)^2)^(b/2)/2)%c;到这里就可以了.
我相信稍微懂点算法的人都可以看出来这是一个递归的过程,如果不理解那么自己再找几个数试一试
理解之后就可以看这个快幂的代码了
int quickMod(int a, int b, int c)
{int ans = 1;while (b){if (b % 2 == 1)ans = (ans * a) % c;b /= 2;a = (a * a) % c;}return ans;
}
这个算法的时间复杂度为O(logn),对于大多数oj网站或者竞赛题相信都可以AC过去。
接下来这种算法虽然思路和上面的完全不一样, 但是其思想核心和上面的算法是有着异曲同工之妙啊。
快幂算法2
我们先将b按2进制展开假设b = 10, 那么b的二进制为1010,也就是0*2^0+1*2^1+0*2^2+1*2^3 = 10;
所以 a^b = a^(0*2^0+1*2^1+0*2^2+1*2^3 ) = a^(2^1) * a(2^3);这种简单的转换在初中就学过了吧,相信大家都懂
所以a^b%c = a^(2^1) * a(2^3) % c =( a^(2^1) % c) * (a(2^3)%c)%c;
讲到这里就可以写代码了
int quickMod(int a, int b, int n)
{int ans = 1;while (b){ if (b & 0x1)<span style="white-space:pre"> </span>//如果二进制位为1ans = ans * a % n;a = a * a % n;b >>= 1;<span style="white-space:pre"> </span>//b向又移1位}return ans;
}
写到这里就差不多该结束了,相信有心的读者可以发现这两种快幂思想的核心都是二分法,所以时间复杂度都为O(logn)。
虽然推倒过程完全不一样,但是到代码实现这个层面几乎是一模一样的,if(b % 2 == 1) 就相当于if(b & 0x1), b /= 2也就是b>>=1。
所以算法是多么优美又多么奇妙,希望大家可以在算法之路上不断前行,继续努力!
也欢迎关注我的公众号,从自身和身边经历聊一些职场话题,带你避坑
快速幂取余算法总结详解相关推荐
- Python实现快速幂取余算法
引子 今天无意中,看到了慧科教育科技集团有限公司-后厂理工学院 的AI相关学员招募信息,要求颇高,还要做编程自测题,并且达到60分才建议进行课程的学习.我忍不住发送了报名信息,得到了自测题.看到了如下 ...
- 【面试相关】python实现快速幂取余算法详解
假设我们要计算 2102^{10}210 对1000取模的结果,可以很简单的得到24.但是如果要求 210002^{1000}21000 对1000取模的结果,常规方法就行不通了,因为常规的变量无法容 ...
- 快速幂||取余运算【模板】(洛谷P1226题题解,Java语言描述)
题目要求 P1226题目链接 分析 标准的快速幂取模算法板子,之前这个算法我在这篇文章中讲过了:<快速幂算法详解&&快速幂取模算法详解>. 这里选择使用比较简单的API实现 ...
- C语言快速幂取模算法小结
资料链接:http://www.jb51.net/article/54947.htm C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速幂,实际上是快 ...
- 【数学】幂运算与快速幂取余
一.幂运算 1.幂的定义: 的幂就是多个相乘,记作,表示的次幂,即个相乘,我们把叫做底数,叫做指数. 2.幂的运算: 我们可以用公式将幂运算进行简化,公式如下: 3.求幂方法: (1). Python ...
- 【算法分析与设计】快速幂算法与快速幂取模算法
文章目录 快速幂算法 算法分析 算法实现 位运算优化 BigInteger支持 快速幂取模算法 算法优点 算法推导 算法实现 BigInteger支持 本文完整代码实现(Java语言描述) 快速幂算法 ...
- 快速幂(快速幂取余)
引入公式 (a*b) %c = ((a % c)*(b % c)) %c 普通求幂的解法 public static int pow(int x,int n) {int result = 1;for ...
- 洛谷 P1226 【模板】快速幂||取余运算
题目描述 给你三个整数 a,b,p,求 a^b mod p. 输入格式 输入只有一行三个整数,分别代表 a,b,p. 输出格式 输出一行一个字符串 a^b mod p=s,其中 a,b,p 分别为题目 ...
- P1226 【模板】快速幂||取余运算
题目描述 给你三个整数 b,p,k,求 b^pmod . 输入格式 输入只有一行三个整数,分别代表 b,p,k 输出格式 输出一行一个字符串 b^p mod k=s,其中 b, p, k分别为题目给定 ...
最新文章
- System.currentTimeMillis()竟然存在性能问题,这我能信?
- pip安装包以后jupyter不能导入的解决办法
- 测试和恢复性的争论:面向对象vs.函数式编程
- cmake ubuntu安装卸载升级
- 安装配置JDK和Eclipse的步骤
- Dockerfile 布局的良好实践
- 人脸检测与识别年度进展概述
- 工作185:解决vue+el-element二级联动,选项选择后不显示的问题
- js控制文本框中的字符数
- ansible安装与配置文件
- 多数据点拟合曲线,最小二乘法,矩阵
- 推荐3个好用的Excel项目管理甘特图模板
- 电脑打开热点后无法连接到网络
- Python-png转换成jpg
- 记一次App异常kill分析处理
- 在JavaScript中创建SVG矢量图EAN13条码
- 解决:No routes matched location “/“
- Sql Server 2008R2 安装教程
- Contradiction Detection with Contradiction-Specific Word Embedding
- 7. 成功解决:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
热门文章
- “我和刘德华直到现在都没离婚”-喻可欣坚称与刘德华已结婚
- 看集装箱号码识别技术如何解决港口拥堵
- macOS Xcode8安装RVM,安装Ruby,安装/卸载Cococapods全程详解
- 作为一个程序员: 这么奇葩搞笑的代码注释你见过吗?
- 雅思备考-口语词组积累-第三章
- css设置元素抛物线,CSS3 抛物线波动(Parabola Wave)
- 简单几步教你如何看k线图图解
- 【学习番外篇】Firefly ROC-RK3328-CC刷Ubuntu18.04+VNC
- 安富莱C语言编码规范
- 【函数参数传递】编写一个函数,统计字符串中小写字母的个数,并把字符串中的小写字母转化成大写字母。