接触ACM没几天,向各路大神求教,听说ACM主要是研究算法,所以便开始了苦逼的算法学习之路。话不多说,RT所示,学习快速求幂。

在头文件<math.h>或是<cmath>中,double pow( double x, double y );函数是用来快速求x^y,于是便从pow函数来说起,以下大体上是pow的函数代码:

  1. int pow(int x, int n)
  2. {
  3. int num = 1;
  4. while (n != 0){
  5. num = num *x;
  6. n = n -1;
  7. }
  8. return num;
  9. }

通过以上程序,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)。通过这种方式,我们可以根据通项公式写出递归函数求分制幂指运算的函数代码:

  1. int DC_pow(int x, int n)
  2. {
  3. if (n==1) return x;
  4. if (n==0) return 1;
  5. else if (n & 1)  return DC_pow(x,n/2)*DC_pow(x, n/2)*x;      //  对应公式x^(n/2) * x^(n/2) * n
  6. else             return DC_pow(x,n/2)*DC_pow(x, n/2);        //  对应公式x^(n/2) * x^(n/2)
  7. }

由此我们以分治思想,减少了运算量。接下来,我们研究此递归代码的一些细节。对于n/2,我们在二进制位运算中还有其他的处理方式,倘若一个数是二进制数,只要我们将该数右移一位(x>>1),即可对其真值除以2。也许你又会想,DG想表述的是什么意思,即使我把代码中的n/2换成n>>1运算量有没有改变,到底意义何在呢?我们从一个例子引出:

♢问题:请求出3^999=?(问题目的在于感受不同求解方法的复杂程度)

分析:我们先调用最最基本的方式进行求解,即为求:3 * 3 * …… * 3(999个3),这样一共要进行998次乘法运算。这种方法显然是太麻烦,反复的递归,计算机心里定会默念“我靠,坑爹啊!”

接下来,我们使用简单分制思想来做此题,这样就可以大大简少运算次数,使得计算次数仅为9次。但是,如果你也在学习ACM的话,你会懂得递归做法运行速度之慢。即使递归函数通俗易懂,即使写法简单,但是并不推荐。你若不信,我给大家举一个简单的例子:

利用欧几里德算法(辗转相除法)计算两数的gcd(最大公约数)

递归形式:

  1. int gcd(int a,int b)
  2. {
  3. if(a == 0) return b;
  4. else return b == 0?a:gcd(b,a%b);
  5. }

非递归形式:

  1. int gcd(int a,int b)
  2. {
  3. int c;
  4. if(a == 0) return b;
  5. while(b!=0) c = b,b = a % b,a = c;
  6. return a;
  7. }

以上利用相同的思想进行求解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次方加入,为假则不加入。下面放出代码:

  1. int spow(int x, int n)
  2. {
  3. int result = 1;
  4. while (n > 0)
  5. {
  6. if (n & 1)   result *= x;
  7. x *= x;
  8. n >>= 1;        //n=n/2
  9. }
  10. return result;
  11. }

以上便是全部内容,第一次发文,多有错误。多多包含。

学习本块知识参考过的博文:

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)相关推荐

  1. LeetCode Super Pow(快速求幂算法)

    题意:给出底数a,指数b(很大的数,用数组形式给出,每个元素为1位),求其对1337的模 思路:在遍历数据过程中,用ans(n)表示上一次计算结果,则ans(n+1) = pow(ans(n), 10 ...

  2. VBA实现矩阵快速求幂

    不管求一个数的幂还是矩阵的幂,比如a^16,把a做15次乘法是最容易想到的方法,但这样效率特别低.其实可以先算出a^2,其平方就是a^4,再平方就是a^8,最后平方一次,就是a^16,只要4次乘法就够 ...

  3. 二分求幂,快速求解a的b次幂

    一个引子 如何求得a的b次幂呢,那还不简单,一个for循环就可以实现! void main(void) {int a, b;int ans = 1;cin >> a >> b; ...

  4. java位运算求幂,程序员必学:快速幂算法

    前阵子,有小伙伴在我B站的算法教程底下留言 小伙伴们有任何疑问或者希望我解说任何内容,都可以在我的小我私家B站或民众号(xmg_mj)留言哦,我会尽我最大能力.只管抽时间去写文章\录视频来回应人人. ...

  5. 分治算法——快速幂(平方求幂)

    分治算法--快速幂(平方求幂) 什么是快速幂呢,我们先来看维基百科对快速幂的解释: 在数学和程序设计中,平方求幂(英语:exponentiating by squaring)或快速幂是快速计算一个数( ...

  6. 数据结构与算法:快速幂——求幂运算 O(logN)

    前言:普通的求幂问题,相信大家已经屡见不鲜,无非就是 纯暴力 解法,或者直接调用公式:Math.Pow(底数, 指数)  一步得出.但这两种算法只能使得时间复杂度保持在 O(n).而且公式一步的得往往 ...

  7. 快速幂与快速矩阵幂(以大数下的斐波那契数列为例)

    一般地,a^n的算法时间复杂度为o(n),但是如果n为大数,则运行时间过长,效率不高.因此,使用二分的思想降低时间复杂度,使其降至o(logn),则会使运行效率较大提升.二分思想如下图所示. 例如:2 ...

  8. 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 ...

  9. HDU1420 Prepared for New Acmer【快速模幂】

    Prepared for New Acmer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/O ...

最新文章

  1. 资讯|WebRTC M92 更新
  2. 浅谈地方门户网站运营思路
  3. C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试
  4. API函数MessageBox的参数与返回值
  5. Java 8 API Stream让List操作更便捷
  6. SqlHelper V1.0 (C#)
  7. 刚入门的UI设计师,需要懂的图标设计规范?
  8. SteinerTree模板
  9. git 常见操作合集
  10. 风扇转速/CPU温度监控工具推荐
  11. RFC2544背靠背测试——信而泰Renix测试软件实操
  12. Elasticsearch检索分类深入详解—基础篇
  13. MatLab 计算开根号
  14. redis雪崩和穿透、击穿的解决方法
  15. win10任务管理器禁用_如何在Windows 10的文件资源管理器中禁用广告和通知
  16. 前端生成二维码图片以及条形码图片
  17. 刚刚涉足神经网络,基于TensorFlow2.0以实现鸢尾花分类为例总结神经网络代码实现的几个步骤,附代码详细讲解
  18. wmware16如何安装win7---超详细
  19. mysql导出xls_MySQL导出 xls上传到异机
  20. 基于360SafeDemo对duilib整体框架的概述

热门文章

  1. Python基础——PyCharm版本——第八章、文件I/O(核心3、csv和excel解析)
  2. 零基础学Python-爬虫-1、网络请求Requests【网络操作理论基础与实践·请认真看看理论,理论基础决定后期高度】
  3. nagios监控-多用户管理
  4. 用户资源管理DBMS_RESOURCE_MANAGER
  5. goldengate的实施过程
  6. H5开发 连接蓝牙打印机 打印标签(斑马ZR628)
  7. 读《三体Ⅱ · 黑暗森林》| 人能相互理解的前提是力量对等
  8. IDEA overwrite报错、languagelevel设置不生效问题
  9. 采用vue-cli安装的一些注意点
  10. python相关工具