如何提高算法收敛速度(快速幂算法详解)
如何提高算法收敛速度(快速幂算法详解)
2024-07-02 02:15:37  作者:情在深处  网址:https://m.xinb2b.cn/tech/uph368647.html
前言

快速幂是什么?

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

有多快?

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

用的多么?

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

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

快速幂介绍

先看个问题再说:

初探

首先问你一个问题,如果让你求 (2^10)00你可能会这样写:

intva=1;for(inti=0;i<10;i ){va*=2;}System.out.println(va000);

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

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

longva=1;for(inti=0;i<50;i ){va*=2;}System.out.println(va);System.out.println(va000);

计算50次出了结果正当你暗暗私喜的时候又来了一个要命的问题:让你算 (2^1e10)000 且不许你用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)10=[2*(2*2···*2)]5=(25)*(2*2···*2%le5)5

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

如何提高算法收敛速度(快速幂算法详解)(1)

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

如何提高算法收敛速度(快速幂算法详解)(2)

快速幂探索

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

如何提高算法收敛速度(快速幂算法详解)(3)

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

如何提高算法收敛速度(快速幂算法详解)(4)

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

如何提高算法收敛速度(快速幂算法详解)(5)

快速幂实现

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

如何提高算法收敛速度(快速幂算法详解)(6)

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

2*2*2*2*2=2*(2*2*2*2)奇数问题可以转化为偶数问题。

这里,递归的解法如下

longc=10000007;publiclongdivide(longa,longb){if(b==0)return1;elseif(b%2==0)//偶数情况returndivide((a%c)*(a%c),b/2)%c;else//奇数情况returna%c*divide((a%c)*(a%c),(b-1)/2)%c;}

非递归实现也不难,控制好循环条件即可:

//求a^b00000007longc=1000000007;publiclongdivide(longa,longb){a%=c;longres=1;for(;b!=0;b/=2){if(b%2==1)res=(res*a)%c;a=(a*a)%c;}returnres;}

对于非递归你可能有点模糊为啥偶数情况不给res赋值。这里有两点:

为奇数的情况res仅仅是收集相乘那个时候落单的a最终b均会降到1,a最终都会和res相乘,不用担心会漏掉理想状态一直是偶数情况,那最后直接获得a取模的值即可。

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

如何提高算法收敛速度(快速幂算法详解)(7)

矩阵快速幂

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

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

如何提高算法收敛速度(快速幂算法详解)(8)

前几个斐波那契的数列为: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)][11]=[f(n),f(n-1)]*[10][11][11]=[f(n-1),f(n-2)]**[10][11]=·······

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

如何提高算法收敛速度(快速幂算法详解)(9)

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

publicintFibonacci(intn){n--;//矩阵为两项inta[][]={{1,1},{1,0}};//进行快速幂的矩阵intb[][]={{1,0},{0,1}};//存储漏单奇数、结果的矩阵,初始为单位矩阵inttime=0;while(n>0){if(n%2==1){b=matrixMultiplication(a,b);}a=matrixMultiplication(a,a);n/=2;}returnb[0][0];}publicint[][]matrixMultiplication(inta[][],intb[][]){//intx=a.length;//a[0].length=b.length为满足条件inty=b[0].length;//确定每一排有几个intc[][]=newint[x][y];for(inti=0;i<x;i )for(intj=0;j<y;j ){//需要确定每一个元素//c[i][j];for(intt=0;t<b.length;t ){c[i][j] =(a[i][t]000)*(b[t][j]000);c[i][j]%=10000;}}returnc;}

结语

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

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

关注回复bigsai领取干货资源。下次再见,打工人!

如何提高算法收敛速度(快速幂算法详解)(10)

如何提高算法收敛速度(快速幂算法详解)(11)

  • 易烊千玺和关晓彤合作遮天(易烊千玺出演遮天叶凡)
  • 2024-07-02易烊千玺出演遮天叶凡改编自辰东小说,由华策克顿出品的东方科幻仙侠英雄剧《遮天》自去年开始就一直在筹备,随着电视剧的启动,令人期待的男女主角人选也越来越受网友期待最近,有媒体爆出《遮天》的男女主角分别为现在最当红的易烊千玺。
  • 赛尔号4月6号最新更新(赛尔号9月9日更新)
  • 2024-07-02赛尔号9月9日更新本周中秋主打精灵,瓦普特号船长瓦普特,有可能740本周中秋免费精灵中秋第二个免费精灵战王的萌皮暗王的皮肤好了本周就到这了,我们下周再见拜拜!,。
  • 苹果xr的型号名称是什么(消息称苹果XR设备代号为)
  • 2024-07-02消息称苹果XR设备代号为IT之家11月2日消息,据Digitimes报道,苹果正精心打造旗下首款XR头戴设备(可能是AR或MR)供应链人士透露,该款名为N301的拓展现实(XR)设备确定由和硕独家做最后组装,预计2023年一。
  • 俄罗斯车臣存在吗(14个国家独立出去)
  • 2024-07-0214个国家独立出去苏联解体之后,整个联盟分化成15个国家,这些国家和当年苏联的主体国俄罗斯,不再具有依附关系,都拥有相当独立的主权和平等的国际地位但是却有这么一个国家,想学其它加盟共和国闹独立,却被俄罗斯极力阻拦俄罗斯。
  • 大江大河片段宋运辉(大江大河2首播感人)
  • 2024-07-02大江大河2首播感人文/马庆云12月20日晚间,电视剧《大江大河2》卫视首播从目前已经播出的前两集剧情内容来看,这部电视剧秉持了首部的故事精神,演绎的依旧是在改开年代当中,几位主人公如何“一心为公”的故事《大江大河》首部。
  • 云南野生松茸几月份上市(昆明新鲜松茸上市)
  • 2024-07-02昆明新鲜松茸上市来源:【昆明日报-掌上春城】进入5月,咱们云南人最爱的野生菌行情如何?记者走访发现,松茸已经上市云南木水花野生菌交易中心的商户告诉记者,4月29日,迪庆维西发现了2022年的第一批新鲜松茸由于量太少,。
  • 开门红什么梗(开门红的解释)
  • 2024-07-02开门红的解释开门红原是比喻在一年开始或一项工作开始时就获得显著的成绩现指多个城市开启复工模式后,高德地图上的道路变“红”第一次看到堵车会开心,只因人山人海才是真的国泰民安引用示例:没想到2020年的“开门红”是这。
  • 华为手环b6怎么与手机配对(华为手环B6今日开售)
  • 2024-07-02华为手环B6今日开售点击右上角关注我们,每天给您带来最新最潮的科技资讯,让您足不出户也知道科技圈大事!对于大部分来说,智能手环和蓝牙耳机是每天都会出门携带的东西在繁忙的工作当中,如果有特别多的电话要接,每次都要拿起手机是。
  • 原神二重证据法怎么完成(原神等量交换完成不了怎么办)
  • 2024-07-02原神等量交换完成不了怎么办许家都想要搞清楚原神等量交换完成不了不可错过,毕竟原神等量交换完成不了怎么办的确很是头疼?很家近期都在讨论这个问题,不少玩家都想知道该怎么完成这个任务,今天就为大家带来关于这个方面的具体介绍,通过下面。
  • 减脂时期饱腹感强的主食(看起来适合减脂)
  • 2024-07-02看起来适合减脂想要减肥一定要吃对东西以下这些最好要避免1、糯玉米升糖热量都很高吃玉米还是普通玉米比较好2、烤红薯红薯和紫薯土豆都一样蒸煮都可以就是不能烤GI值会飙升3、土豆泥把土豆搅成泥GI值也会上升一大块4、米粉。
  • 海上孟府饰演孟文禄爷爷的是哪位演员
  • 2024-07-02海上孟府饰演孟文禄爷爷的是哪位演员海上孟府演员表(主演)  孟文禄(段奕宏饰)孟文禄的饰演者段奕宏介绍:  段奕宏,汉,出生于1973年5月16日,原名段龙,演员1998年毕业于中央戏剧学院表演系,毕业后进入中国国家话剧院,2009年。