初学 快速幂 的理解
博客停了差不多三个月, 虽然这一段时间在学算法, 但从来没有写博客。 今天看了一上午的快速幂,突然想写写博客, 增加一下自己的记忆!这个博文知识简单介绍一下算法中取余的原因
1 至于快速幂的概念不详细记录了。当我们想求a的b次幂对c取余时,我们会直接想到用这个算法:
int ans = 1;for( i = 1; i <= b; i++){ans = ans * a;}ans %= c;
这个算法的时间复杂度体现在for循环中,为O(b).这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。因此需要用到离散数学知识(该知识点我也没学过,度娘教的^_^)
定理1:
2 由上面的公式可以推出:
把a看成 a * 1, 故由定理1可得出上面的公式。由此得到改进版本:
int ans = 1; a = a % c; //加上这一句for(int i = 1;i<=b;i++){ ans = (ans * a) % c;//这里再取了一次余 } ans = ans % c;
这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,所以,我们推出以下的快速幂算法。
3 快速幂算法依赖于以下明显的公式,我就不证明了,很简单理解。
4 由此得到改进版本:
int ans = 1;a = a % c;if(b%2==1) ans = (ans * a) mod c; //如果是奇数,要多求一步,可以提前算到ans中 k = (a*a) % c; //我们取a2而不是afor(int i = 1;i<=b/2;i++){ ans = (ans * k) % c;} ans = ans % c;
5 我们可以看到,我们把时间复杂度变成了O(b/2).当然,这样子治标不治本。但我们可以看到,当我们令k = (a * a) mod c时,
状态已经发生了变化,我们所要求的最终结果即为(k)^b/2 mod c而不是原来的a^b mod c,所以我们发现这个过程是可以迭代下去的。
((迭代就是把这一次算的值作为下一次循环的初始值,所以可以更简化该算法))
当然,对于奇数的情形会多出一项a mod c,所以为了完成迭代,当b是奇数时,我们通过 ans = (ans * a) % c;来弥补多出来的这一项,
此时剩余的部分就可以进行迭代了。 形如上式的迭代下去后,当b=0时,所有的因子都已经相乘,算法结束。于是便可以在O(log b)的时间内完成了。
于是,有了最终的算法:快速幂算法。
((说实话, 我对这个简化有点糊涂,关于在O(log b)的时间内就可以完成, 就假装懂了吧, 以后慢慢理解吧))
6
int ans = 1;a = a % c;while(b>0){ if(b % 2 == 1) ans = (ans * a) % c;b = b/2; a = (a * a) % c; }
7 将上述的代码结构化,也就是写成函数:
int PowerMod(int a, int b, int c){ int ans = 1;a = a % c;while(b>0) { if(b % 2 = = 1) ans = (ans * a) % c;b = b/2; a = (a * a) % c; }return ans;}
这就是最后的优化代码了。以上内容是抄袭的, 只不过自己又写了一遍。如果看不懂我写的的可以点下面网址:
http://wenku.baidu.com/link?url=PdtuRuYTZSIfAC3TZCiHSx3fk7cEn3yuZBiYwbx-b7h_TOxNyOQtNOaUepEmxw56jhnPePqAdebOH6QL- pvmhFCYYdzGhYRneUM_oZTpxwO
有关于快速幂的算法的推导,还可以从另一个角度来想。我就不介绍了。
转载于:https://www.cnblogs.com/lj-1568/p/4754336.html
初学 快速幂 的理解相关推荐
- 数论基础之快速幂(详细教程)
2020.2.17更新,将模板改为c++版,以及增加了对循环版快速幂的理解 一.问题引入 求 anmodpa^n \ mod \ pan mod p 的结果 分析 思路:看到这样的题目,我们最容易想到 ...
- hdu 2035 人见人爱A^B (快速幂)
人见人爱A^B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- 矩阵的乘法和快速幂的一些理解(适用初学者)
矩阵是线性代数的知识...后悔没好好学了... 第一部分:矩阵的基础知识 1.结合性 (AB)C=A(BC). 2.对加法的分配性 (A+B)C=AC+BC,C(A+B)=CA+CB . 3.对数乘的 ...
- 快速幂实现pow函数(从二分和二进制两种角度理解快速幂)
文章目录 迭代实现快速幂 思路 int的取值范围 快速幂 从二进制的角度来理解 从二分法的角度来理解 代码 复杂度分析 进阶--超级次方 思路 倒序+快速幂 正序+快速幂 代码 复杂度分析 迭代实现快 ...
- 快速幂(二进制理解)
一.题目背景 已知底数a,指数b,取模值mod. 求ans = a^b % mod 二.朴素算法(已知可跳过) ans = 1,循环从 i 到 b ,每次将 ans = ans * a % mo 时间 ...
- 矩阵快速幂求斐波那契数列(初学整理)
参考文章: http://blog.csdn.net/u013795055/article/details/38599321 http://blog.csdn.net/g_congratulation ...
- 快速幂算法(理解快速幂只需两道题)
重点看代码注释 题目 2088: [蓝桥杯]快速幂 时间限制: 1Sec 内存限制: 128MB 题目描述 给定A, B, P,求(A^B) mod P. 输入 输入共一行. 第一行有三个数,N, M ...
- 完全理解乘法快速幂及其两种写法的解析
an=?0≤n≤10105an=?0≤n≤10105 a^n=? \qquad 0 \le n \le 10^{10^5} 没错,乘法快速幂就是解决上述问题的. 乘法快速幂的思想 可以看到,要求一个数 ...
- LeetCode50——一题学会快速幂算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的第31篇文章,我们来看下LeetCode的第50题,求一个数的幂. 题意 这道题的题意只有一句话,就是给定两个数x和 ...
最新文章
- 测试与封装5.1.5.2
- 数据结构 -- 散列表
- Hbase的过滤器查询
- Listener监听器之HttpSessionListener
- [Android]ListView性能优化之视图缓存
- php+mysql 大容量数据高效分页效果(弃用limit)
- bzoj1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
- commons-fileupload 图片上传示例
- 芦溪中学2021高考成绩查询,三台县芦溪中学2021年招生简章
- 中国什么时候才能全面普及 1 Gbps 下行的网速?
- 第九章 单处理器调度
- grep, egrep
- mongodb java 开源_开源的Mongodb java client -- mango发布
- mysql sqlserver alter语句区别_SQL ALTER
- brave浏览器_升华拜克股票行情:Brave推出适用于PC和移动设备的以隐私为中心的广告拦截浏览器v1.0...
- Selenium 方法封装 一
- VS2010 C# 调用Web Service
- Linux中的用户切换:su和su - 的区别
- python 知乎接口_ZhihuVAPI 是一个可以让你以一种优雅的形式调用知乎数据的 Python 包....
- NTFS, FAT32和exFAT文件系统有什么区别