快速求幂(Quick Exponentiation)
接触ACM没几天,向各路大神求教,听说ACM主要是研究算法,所以便开始了苦逼的算法学习之路。话不多说,RT所示,学习快速求幂。
在头文件<math.h>或是<cmath>中,double pow( double x, double y );函数是用来快速求x^y,于是便从pow函数来说起,以下大体上是pow的函数代码:
- int pow(int x, int n)
- {
- int num = 1;
- while (n != 0){
- num = num *x;
- n = n -1;
- }
- return num;
- }
通过以上程序,2^5 = 2*2*2*2*2的流程中一共进行了4次乘法。试想若是大数2^99999999.......,这样循环的算下来肯定要计算到猴年马月。那么我们有什么办法可以简化我们的幂指运算呢?
分析数据
2^4=2^2 * 2^2;
2^5=2^2 * 2^2 * 2
2^6=2^3 * 2^3
2^7=2^3 * 2^3 * 2
……
x^n = x^(n/2) * x^(n/2) (n为偶数)
x^n = x^(n/2) * x^(n/2) * n (n为奇数)
显然这种算法分析利用分治思想(divide and conquer)。通过这种方式,我们可以根据通项公式写出递归函数求分制幂指运算的函数代码:
- int DC_pow(int x, int n)
- {
- if (n==1) return x;
- if (n==0) return 1;
- else if (n & 1) return DC_pow(x,n/2)*DC_pow(x, n/2)*x; // 对应公式x^(n/2) * x^(n/2) * n
- else return DC_pow(x,n/2)*DC_pow(x, n/2); // 对应公式x^(n/2) * x^(n/2)
- }
由此我们以分治思想,减少了运算量。接下来,我们研究此递归代码的一些细节。对于n/2,我们在二进制位运算中还有其他的处理方式,倘若一个数是二进制数,只要我们将该数右移一位(x>>1),即可对其真值除以2。也许你又会想,DG想表述的是什么意思,即使我把代码中的n/2换成n>>1运算量有没有改变,到底意义何在呢?我们从一个例子引出:
♢问题:请求出3^999=?(问题目的在于感受不同求解方法的复杂程度)
分析:我们先调用最最基本的方式进行求解,即为求:3 * 3 * …… * 3(999个3),这样一共要进行998次乘法运算。这种方法显然是太麻烦,反复的递归,计算机心里定会默念“我靠,坑爹啊!”
接下来,我们使用简单分制思想来做此题,这样就可以大大简少运算次数,使得计算次数仅为9次。但是,如果你也在学习ACM的话,你会懂得递归做法运行速度之慢。即使递归函数通俗易懂,即使写法简单,但是并不推荐。你若不信,我给大家举一个简单的例子:
利用欧几里德算法(辗转相除法)计算两数的gcd(最大公约数)
递归形式:
- int gcd(int a,int b)
- {
- if(a == 0) return b;
- else return b == 0?a:gcd(b,a%b);
- }
非递归形式:
- int gcd(int a,int b)
- {
- int c;
- if(a == 0) return b;
- while(b!=0) c = b,b = a % b,a = c;
- return a;
- }
以上利用相同的思想进行求解a,b的gcd,但是效率有很大偏差,大家可以尝试。
那么,还有什么方法来求解这个问题呢,接下来便是经典的快速求幂法。我们将3^999进行分解,即为: (3 ^ 512) * (3 ^ 256) * (3 ^ 128) * (3 ^ 64) * (3 ^ 32) * (3 ^ 4) * (3 ^ 2) * 3。这时候,我们可以整理出3的指数部分形式:2^9+2^8+2^7+2^6+2^2+2^1+2^0。然后,我们再把999转换成2进制为1111100111,2进制的转换作为指数位置的数。由此,我们同样的利用了分治思想,将指数分成了2的n次方和的形式。配合上右移运算,我们只要将其二进制数与1做与运算,为真则将此位上的2^n次方加入,为假则不加入。下面放出代码:
- int spow(int x, int n)
- {
- int result = 1;
- while (n > 0)
- {
- if (n & 1) result *= x;
- x *= x;
- n >>= 1; //n=n/2
- }
- return result;
- }
以上便是全部内容,第一次发文,多有错误。多多包含。
学习本块知识参考过的博文:
http://blog.csdn.net/zhizichina/article/details/7573342
http://blog.csdn.net/hkdgjqr/article/details/5381028
关于快速求幂的ACM题集:
HDU1575、HDU1852、HDU2817、HDU2035.
转载于:https://www.cnblogs.com/Destiny-Gem/p/qpow.html
快速求幂(Quick Exponentiation)相关推荐
- LeetCode Super Pow(快速求幂算法)
题意:给出底数a,指数b(很大的数,用数组形式给出,每个元素为1位),求其对1337的模 思路:在遍历数据过程中,用ans(n)表示上一次计算结果,则ans(n+1) = pow(ans(n), 10 ...
- VBA实现矩阵快速求幂
不管求一个数的幂还是矩阵的幂,比如a^16,把a做15次乘法是最容易想到的方法,但这样效率特别低.其实可以先算出a^2,其平方就是a^4,再平方就是a^8,最后平方一次,就是a^16,只要4次乘法就够 ...
- 二分求幂,快速求解a的b次幂
一个引子 如何求得a的b次幂呢,那还不简单,一个for循环就可以实现! void main(void) {int a, b;int ans = 1;cin >> a >> b; ...
- java位运算求幂,程序员必学:快速幂算法
前阵子,有小伙伴在我B站的算法教程底下留言 小伙伴们有任何疑问或者希望我解说任何内容,都可以在我的小我私家B站或民众号(xmg_mj)留言哦,我会尽我最大能力.只管抽时间去写文章\录视频来回应人人. ...
- 分治算法——快速幂(平方求幂)
分治算法--快速幂(平方求幂) 什么是快速幂呢,我们先来看维基百科对快速幂的解释: 在数学和程序设计中,平方求幂(英语:exponentiating by squaring)或快速幂是快速计算一个数( ...
- 数据结构与算法:快速幂——求幂运算 O(logN)
前言:普通的求幂问题,相信大家已经屡见不鲜,无非就是 纯暴力 解法,或者直接调用公式:Math.Pow(底数, 指数) 一步得出.但这两种算法只能使得时间复杂度保持在 O(n).而且公式一步的得往往 ...
- 快速幂与快速矩阵幂(以大数下的斐波那契数列为例)
一般地,a^n的算法时间复杂度为o(n),但是如果n为大数,则运行时间过长,效率不高.因此,使用二分的思想降低时间复杂度,使其降至o(logn),则会使运行效率较大提升.二分思想如下图所示. 例如:2 ...
- 51Nod-1046 A^B Mod C【快速模幂】
1046 A^B Mod C 基准时间限制:1秒 空间限制:131072KB 分值:0难度:基础题 给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. I ...
- HDU1420 Prepared for New Acmer【快速模幂】
Prepared for New Acmer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
最新文章
- 资讯|WebRTC M92 更新
- 浅谈地方门户网站运营思路
- C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试
- API函数MessageBox的参数与返回值
- Java 8 API Stream让List操作更便捷
- SqlHelper V1.0 (C#)
- 刚入门的UI设计师,需要懂的图标设计规范?
- SteinerTree模板
- git 常见操作合集
- 风扇转速/CPU温度监控工具推荐
- RFC2544背靠背测试——信而泰Renix测试软件实操
- Elasticsearch检索分类深入详解—基础篇
- MatLab 计算开根号
- redis雪崩和穿透、击穿的解决方法
- win10任务管理器禁用_如何在Windows 10的文件资源管理器中禁用广告和通知
- 前端生成二维码图片以及条形码图片
- 刚刚涉足神经网络,基于TensorFlow2.0以实现鸢尾花分类为例总结神经网络代码实现的几个步骤,附代码详细讲解
- wmware16如何安装win7---超详细
- mysql导出xls_MySQL导出 xls上传到异机
- 基于360SafeDemo对duilib整体框架的概述
热门文章
- Python基础——PyCharm版本——第八章、文件I/O(核心3、csv和excel解析)
- 零基础学Python-爬虫-1、网络请求Requests【网络操作理论基础与实践·请认真看看理论,理论基础决定后期高度】
- nagios监控-多用户管理
- 用户资源管理DBMS_RESOURCE_MANAGER
- goldengate的实施过程
- H5开发 连接蓝牙打印机 打印标签(斑马ZR628)
- 读《三体Ⅱ · 黑暗森林》| 人能相互理解的前提是力量对等
- IDEA overwrite报错、languagelevel设置不生效问题
- 采用vue-cli安装的一些注意点
- python相关工具