前言

快速幂是什么?顾名思义,快速幂就是快速算底数的n次幂。

有多快?其时间复杂度为 O(log₂n), 与朴素的O(n)相比效率有了极大的提高。

用的多么?快速幂属于数论的范畴,本是ACM经典算法,但现在各厂对算法的要求越来越高,并且快速幂适用场景也比较多并且相比朴素方法有了非常大的提高。所以掌握快速幂算法已经是一名更合格的工程师必备要求!

下面来详细看看快速幂算法吧!

快速幂介绍

先看个问题再说:

初探

首先问你一个问题,如果让你求 (2^10)%1000你可能会这样写:int va=1;

for(int i=0;i<10;i++)

{

va*=2;

}

System.out.println(va%10000);

熟悉的1024没问题,总共计算了10次。但是如果让你算 (2^50)%10000呢?

你可能会窃喜,小样,这就想难住我?我知道int只有32位,50位超出范围会带来数值越界的异常,我这次可以用long,long有64位呢!long va=1;

for(int i=0;i<50;i++)

{

va*=2;

}

System.out.println(va);

System.out.println(va%10000);

计算50次出了结果正当你暗暗私喜的时候又来了一个要命的问题:让你算 (2^1e10)%10000 且不许你用Java大数类,你为此苦恼不知所措。这时bigsai小哥哥让你百度下取模运算,然后你恍然大悟,在纸上写了几个公式:(a + b) % p = (a % p + b % p) % p  (1)

(a - b) % p = (a % p - b % p ) % p (2)

(a * b) % p = (a % p * b % p) % p  (3)

a ^ b % p = ((a % p)^b) % p        (4)

你还算聪明一眼发现其中的规律:(a * b) % p = (a % p * b % p) % p   (3)

(2*2*2···*2) %1e10=[2*(2*2···*2)]%1e5=(2%1e5)*(2*2···*2%le5)%1e5

凭借这个递推你明白:每次相乘都取模。机智的你pia pia写下以下代码,却发现另一个问题:怎么跑不出来?

咱们打工人需要对计算机运行速度和数值有一个大致的概念。循环体中不同操作占用时间不同,所以当你的程序循环次数到达1e6或1e7的时候就需要非常非常小心了。如果循环体逻辑或者运算较多可能非常非常慢。

快速幂探索

机智的你不甘失败,开始研究其数的规律,将这个公式写在手上、膀子上、小纸条上。吃饭睡觉都在看:

然后你突然发现其中的奥秘,n次幂可以拆分成一个平方计算后就剩余n/2的次幂了:

现在你已经明白了快速幂是怎么回事,但你可能有点上头,还是给我讲了很多内容:

快速幂实现

至于快速幂已经懂了,我们该怎么实现这个算法呢?

说的不错,确实有递归和非递归的实现方式,但是递归使用的更多一些。在实现的时候,注意一下奇偶性、停止条件就可以了,奇数问题可以转换为偶数问题:2*2*2*2*2=2 * (2*2*2*2) 奇数问题可以转化为偶数问题。

这里,递归的解法如下:long c=10000007;

public  long divide(long a, long b){

if (b == 0)

return 1;

else if (b % 2 == 0) //偶数情况

return divide((a % c) * (a % c), b / 2) % c;

else//奇数情况

return a % c * divide((a % c) * (a % c), (b - 1) / 2) % c;

}

非递归实现也不难,控制好循环条件即可://求 a^b%1000000007

long c = 1000000007;

public  long divide(long a, long b){

a %= c;

long res = 1;

for (; b != 0; b /= 2) {

if (b % 2 == 1)

res = (res * a) % c;

a = (a * a) % c;

}

return res;

}

对于非递归你可能有点模糊为啥偶数情况不给res赋值。这里有两点:为奇数的情况res仅仅是收集相乘那个时候落单的a

最终b均会降到1,a最终都会和res相乘,不用担心会漏掉

理想状态一直是偶数情况,那最后直接获得a取模的值即可。

如果还是不懂,可以用这个图来解释一下:

矩阵快速幂

你以为这就结束了?虽然快速幂主要内容就是以上内容,但是总有很多牛人能够发现很有趣的规律—矩阵快速幂。如果你没听过的话建议仔细看看了解一下。

大家都知道斐波那契数列:的规则:

前几个斐波那契的数列为:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

斐波那契从递推式就可以看出是指数级别的增长,所以稍微多几个数字就是爆炸式增长,所以很多时候也会要求最后几位的结果。有了前面模运算公式溢出就不成问题,但n如果非常非常大怎么快速计算就成了一个新的问题。

我们看下面一组公式:f(n+1) = f(n)   + f(n-1)

f(n)   = f(n)

如果将f(n)和f(n-1)放到一个矩阵中(一行两列):[f(n+1),f(n)]能否找到和[f(n),f(n-1)]之间的什么规律呢?

答案是存在规律的,看上面的公式知道[f(n+1),f(n)]

=[f(n)+f(n-1),f(n)]

[1  1]

=[f(n),f(n-1)]  *

[1  0]

[1  1] [1   1]

=[f(n-1),f(n-2)]*      *

[1  0] [1   1]

=·······

所以现在你可以知道它的规律了吧,这样一直迭代到f(2),f(1)刚好都为1,所以这个斐波那契的计算为:

而这个矩阵有很多次幂,就可以使用快速幂啦,原理一致,你只需要写一个矩阵乘法就可以啦,下面提供一个矩阵快速幂求斐波那契第n项的后三位数的模板,可以拿这个去试一试poj3070的题目啦。public int Fibonacci(int n){

n--;//矩阵为两项

int a[][]= {{1,1},{1,0}};//进行快速幂的矩阵

int b[][]={{1,0},{0,1}};//存储漏单奇数、结果的矩阵,初始为单位矩阵

int time=0;

while(n>0)

{

if(n%2==1)

{

b=matrixMultiplication(a, b);

}

a=matrixMultiplication(a, a);

n/=2;

}

return b[0][0];

}

public  int [][]matrixMultiplication(int a[][],int b[][]){//

int x=a.length;//a[0].length=b.length 为满足条件

int y=b[0].length;//确定每一排有几个

int c[][]=new int [x][y];

for(int i=0;i

for(int j=0;j

{

//需要确定每一个元素

//c[i][j];

for(int t=0;t

{

c[i][j]+=(a[i][t]%10000)*(b[t][j]%10000);

c[i][j]%=10000;

}

}

return c;

}

结语

这篇到这里就肝完啦,其实快速幂的内容还不止这么多,尤其是矩阵快速幂,会有着各种巧妙的变形,不过跟数学有一些关系,这年头,不会点算法、不会点数学真的是举步维艰。所以大家要对本篇内容好好吸收,让我那么久的努力发挥出作用。

如果有疑问不懂得欢迎私聊我讨论。也希望大家点个在看,您的支持是我努力的不断动力。

mysql 幂运算_算法—史上最好快速幂算法讲解相关推荐

  1. 史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!!

    史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!! 史上最系统的算法与数据结构书籍推荐!!!!!吐血整理!! 前言:技术书阅读方法论 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在 ...

  2. 史上最清晰的函数空间讲解

    史上最清晰的函数空间讲解 1.什么是数学的空间? 数学的空间定义了研究工作的对象和遵循的规则,研究工作的对象在空间中称之为元素,遵循的规则在空间中称之为结构,结构有线性结构(加法和数乘)和拓扑结构(距 ...

  3. HikariCP-史上最快速的连接池

    转载自 HikariCP-史上最快速的连接池 背景 我们知道的连接池有C3P0,DBCP,它们都比较成熟稳定,但性能不是十分好. 所以有了BoneCP这个连接池,它是一个高速.免费.开源的JAVA连接 ...

  4. 史上最全电子元器件知识讲解

    史上最全电子元器件知识讲解 2016-05-10 半导体行业观察 芯榜(IC行业排行榜) 芯榜 - IC服务平台,用数据读懂芯片业. 转载于:https://www.cnblogs.com/sunny ...

  5. 史上最大,人工智能算法模型 GPT-3 问世,这意味着什么?

    作者 | 谭婧 来源 | 亲爱的数据 封图 | CSDN 付费下载自东方 IC 2020年,年中. 人类历史上最大的人工智能模型,来到人间. 这个体格巨大的北鼻,哭声嘹亮,告知全世界:"我写 ...

  6. 史上最强数据结构----算法的时间复杂度和空间复杂度

    第二章 算法的时间复杂度和空间复杂度 1.算法效率 2 时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3 时间复杂度的计算举例 2.3.1 实例1 2.3.2 实例2 2.3.3 ...

  7. 计算机最快的算法,史上14个最快速算法:孩子的计算能力爆表!大脑堪比计算机!...

    计算是人们生活中经常运用的数学知识,培养小学生的计算能力尤为重要.计算在数学中占有很大的比例,计算教学是小学数学教学中的重要环节,几乎所有的数学知识的学习都离不计算.因此,教师在教学过程中应充分认识计 ...

  8. centos安装mysql 简书_在centos上安装mysql

    由于mysql易主甲骨文以后,centos7担心mysql慢慢会封闭不再开源所以将yum里面的数据库更换名字为MariaDB.两者差不多没有太大区别. 如何在centos7上安装mysql 解决思路通 ...

  9. 苹果几是双卡双待_苹果史上首款实体双卡双待小屏iPhone诞生,值得入手吗?

    如果一说到实体双卡双待iPhone手机,大家第一印象估计是iPhone XR和iPhone XS max吧!现在小编要告诉你的是,就在今天凌晨,史上最小屏幕尺寸的实体双卡双待iPhone 诞生了.没错 ...

最新文章

  1. linux驱动:i2c驱动(四)流程图之注册驱动
  2. python在哪里写程序和运行-Python程序的编写和运行方式有两种()
  3. ES6新特性之解构表达式
  4. centos7.3 mysql5.7_CentOS7.3 yum install MySQL5.7
  5. 如何批量查询PR值、百度权重、百度快照及收录量,用BlueCatTools批量网站查询工具
  6. linux环境下rocketMq双master集群搭建
  7. HDU1231 最大连续子序列【最大子段和】
  8. oracle把列数据串成一个字符串,一组数据,如何根据一个字段值分组后,把另一字段的字符串累加连接起来?...
  9. [Pro]斐波那契数列阿【斐波那契数列】
  10. java socket是什么_Java网络编程-JavaSocket编程是什么呢?
  11. 完整计算器java代码_计算器java代码
  12. python在线问卷调查系统_GitHub - imze/surveySystem: 问卷调查系统
  13. C# 高并发获取唯一ID算法
  14. NVML编译官方用例报错
  15. 极速office(Word)怎么调出标尺
  16. 秒针计时器 html,js实现秒表计时器
  17. EPC概念、EPC编码、EPC标签
  18. java+分割+汉字和英文_Java分割中英文,并且中文不能分割一半?
  19. 提问之前我们应该做些什么 -Leo读提问的智慧 1
  20. 前端开发网页设计(一) :HTML学习

热门文章

  1. Vim实用技巧:global命令
  2. 去掉h1 h2 h3 h4加粗并统一字体大小
  3. 百度搜索命令与谷歌搜索命令汇总
  4. javafx 多线程赛马设计
  5. 头牌知产介绍洗碗机商标注册应选择哪一类?
  6. 2022上半年软考电子证书查询已开通
  7. 结构体的对齐规则及举例
  8. 永远的伊苏 2 Mac版 | 适用于MacOS10.15系统的经典游戏《永远的伊苏 2》中文版
  9. BeautifulSoup爬取豆瓣电影数据
  10. 毫无争议的 GitHub 顶级有用的开源项目排行榜