快速幂(转)

a^b%c 的三种形式 求a^b%c,(1 阅读详情

快速幂取模算法

在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~

所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。[有读者反映在讲快速幂部分时有点含糊,所以在这里对本文进行了修改,作了更详细的补充,争取让更多的读者一目了然]

我们先从简单的例子入手:求= 几。

算法1.首先直接地来设计这个算法:

int ans = 1;

for(int i = 1;i<=b;i++)

{

ans = ans * a;

}

ans = ans % c;

这个算法的时间复杂度体现在for循环中,为O(b).这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。

那么,我们先来看看第一个改进方案:在讲这个方案之前,要先有这样一个公式:

.这个公式大家在离散数学或者数论当中应该学过,不过这里为了方便大家的阅读,还是给出证明:

引理1:

上面公式为下面公式的引理,即积的取余等于取余的积的取余。

证明了以上的公式以后,我们可以先让a关于c取余,这样可以大大减少a的大小,

于是不用思考的进行了改进:

算法2:

int ans = 1;

a = a % c; //加上这一句

for(int i = 1;i<=b;i++)

{

ans = ans * a;

}

ans = ans % c;

聪明的读者应该可以想到,既然某个因子取余之后相乘再取余保持余数不变,那么新算得的ans也可以进行取余,所以得到比较良好的改进版本。

算法3:

int ans = 1;

a = a % c; //加上这一句

for(int i = 1;i<=b;i++)

{

ans = (ans * a) % c;//这里再取了一次余

}

ans = ans % c;

这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,所以,我们推出以下的快速幂算法。

快速幂算法依赖于以下明显的公式,我就不证明了。

有了上述两个公式后,我们可以得出以下的结论:

1.如果b是偶数,我们可以记k = a2 mod c,那么求(k)b/2 mod c就可以了。

2.如果b是奇数,我们也可以记k = a2 mod c,那么求

((k)b/2 mod c × a ) mod c =((k)b/2 mod c * a) mod c 就可以了。

那么我们可以得到以下算法:

算法4:

int ans = 1;

a = a % c;

if(b%2==1)

ans = (ans * a) mod c; //如果是奇数,要多求一步,可以提前算到ans中

k = (a*a) % c; //我们取a2而不是a

for(int i = 1;i<=b/2;i++)

{

ans = (ans * k) % c;

}

ans = ans % c;

我们可以看到,我们把时间复杂度变成了O(b/2).当然,这样子治标不治本。但我们可以看到,当我们令k = (a * a) mod c时,状态已经发生了变化,我们所要求的最终结果即为(k)b/2 mod c而不是原来的ab mod c,所以我们发现这个过程是可以迭代下去的。当然,对于奇数的情形会多出一项a mod c,所以为了完成迭代,当b是奇数时,我们通过

ans = (ans * a) % c;来弥补多出来的这一项,此时剩余的部分就可以进行迭代了。

形如上式的迭代下去后,当b=0时,所有的因子都已经相乘,算法结束。于是便可以在O(log b)的时间内完成了。于是,有了最终的算法:快速幂算法。

算法5:快速幂算法

int ans = 1;

a = a % c;

while(b>0)

{

if(b % 2 == 1)

ans = (ans * a) % c;

b = b/2;

a = (a * a) % c;

}

将上述的代码结构化,也就是写成函数:

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;

}

本算法的时间复杂度为O(logb),能在几乎所有的程序设计(竞赛)过程中通过,是目前最常用的算法之一。

以下内容仅供参考:

扩展:有关于快速幂的算法的推导,还可以从另一个角度来想。

=? 求解这个问题,我们也可以从进制转换来考虑:

将10进制的b转化成2进制的表达式:

那么,实际上,.

所以

注意此处的要么为0,要么为1,如果某一项,那么这一项就是1,这个对应了上面算法过程中b是偶数的情况,为1对应了b是奇数的情况[不要搞反了,读者自己好好分析,可以联系10进制转2进制的方法],我们从依次乘到。对于每一项的计算,计算后一项的结果时用前一项的结果的平方取余。对于要求的结果而言,为时ans不用把它乘起来,[因为这一项值为1],为1项时要乘以此项再取余。这个算法和上面的算法在本质上是一样的,读者可以自行分析,这里我说不多说了,希望本文有助于读者掌握快速幂算法的知识点,当然,要真正的掌握,不多练习是不行的。

By 夜せ︱深

(详细)快速幂算法及效率分析 大数幂乘 快速幂取余(附测试时间) 快速幂 问题:求a^b % m,即a的b次方对m取余的结果。 只要学过C语言的循环就可以写出最简单的朴素版本: 朴素版 typedef long long LL; LL normal_Edition(LL a, LL b, LL m) {//朴素版本 LL ans = 1; for(int i = 0; i < b; ++i) ans *= a; ans = ans % m; return ans; } 时间复杂度O(b),空间复杂度达到了惊人的O(a 阅读详情

相关推荐

【算法】大数取模、逆元、快速幂的原理实现和细节

少了一个%p卡了半个下午…希望下次没有这么弱智的错误了(下次一定

weixin_45570710的博客 2062

杭电 HDU ACM 1061 Rightmost Digit

Rightmost Digit   Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 37888    Accepted Submission(s): 14268     Problem Description Given a ...

舒哥的blog 3597

MTK眼中6G物理层与无线协议的进化之路

提议统一波束和小区级的测量、报告和切换框架/流程,进一步减少移动性切换过程中的中断,采用可扩展框架/流程,允许在不同移动性场景中进行部分用户设备配置更新以实现快速切换,支持用户设备发起的移动性(同步/切换)以降低延迟和因信令交换导致的失败,设计移动性RS以实现空闲状态下的节能和连接状态下的无缝用户体验,实现5G/6G间的无缝互操作移动性,为固定无线接入(FWA)提供潜在增强,构建统一的跨层移动性框架以降低复杂度、减少中断和失败。为适应多样化的流量类型,需要灵活的帧结构和高层时间对齐。

asd199086的博客 1745

快速幂取模——C语言

快速幂取模 快速幂 个人理解的快速幂其实就是把a^b的幂给拆开,把一件复杂的事情拆分为多件事情,而计算机可以同步做多件事情而时间就比做一件复杂的事情节省了很多。而快速幂利用了位运算恰好可以将幂给拆开。如果对位运算不了解的可以先了解位运算相关知识,否则会想我开始一样看不懂快速幂的公式。 int Pow(int a,int b) //a^b { int ans=1;//最终的ans为a^...

weixin_45823991的博客 2779

如何在INCA中修改标定量的初始值,并刷回控制器

测试过程中,有些时候,标定量来不及修改,这就需要修改标定量的初始值了,又不想打开模型重新编译,因此直接在INCA中修改,然后再刷回控制器,就成了最佳选择,之前也学过,长时间不用,忘记怎么搞了,最近又用到了,这次记录一下,以后用到的时候,就不用在网上东翻西找了。截止到2023年11月24日,共找到了两种方法可以实现修改。

weixin_43406519的博客 4200

量化投资从0开始系列 ---- 15. 郑商所日统计数据

前面已经提取了其它期货交易所的数据,最后还剩下郑商所。相比而言,郑商所的数据获取比其它几个交易所更麻烦一点。因为郑商所的系统接口有两个,在2015年11月11日前后发生了切换,这个日期之前是老系统的api接口,这个日期之后是一个新的api接口。 具体的地址在哪里,还是依靠在浏览器中按F12来确定,最后发现的地址是: if trade_date > '20151111': czce_url = f'http://www.czce.com.cn/cn/DFSS

kengxie的博客 2112

[转]快速矩阵快速幂

大学生程序代写 矩阵 快速幂 出处:http://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html 矩阵的快速幂是用来高效地计算矩阵的高次方的。将朴素的o(n)的时间复杂度,降到log(n)。 这里先对原理(主要运用了矩阵乘法的结合律)做下简单形象的介绍: 一般一个矩阵的n次...

weixin_30820077的博客 62

AVM环视算法实战:从3D碗型投影到多场景模式切换的实现与优化

本文深入探讨了AVM环视算法在3D碗型投影和多场景模式切换中的实现与优化。通过分析3D碗型投影的核心原理和动态视角调节技术,展示了如何实现从超广角模式到转向模式的无缝切换。文章还分享了性能优化实战经验,包括实时性提升和图像拼接质量优化,为开发者提供了宝贵的AVM系统开发指南。

weixin_42573113的博客 169

快速幂讲解(转)+自己的一点思考

引言: 我们发现,在int型下使用pow函数求5的三次方,结果为124。 如图: 原因: pow函数的返回值为double型,因浮点数长度问题,存在截断误差。 解决方法: 将变量定义为double型 有没有更快求幂的方法? 假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b),即是O(n)级别。但快速幂能做到O(logn)的复杂度。 快速幂: ...

^.^ 419

IgH EtherCAT 从入门到精通:第 3 章 第一次运行 Hello EtherCAT

摘要:启动EtherCAT主站实践指南 本章详细介绍了如何配置和启动EtherCAT主站系统,主要内容包括: 配置文件详解:讲解/etc/ethercat.conf中的关键配置项,包括主网卡指定、冗余备份设置和网卡驱动选择。 启动流程:说明通过systemd服务和手动命令两种方式加载内核模块,重点介绍了ec_master和ec_generic模块的加载顺序及验证方法。 命令行工具:列举ethercat工具的常用命令,如查看主站状态、扫描从站设备、读取PDO/SDO数据等。 示例程序:简要介绍内核态示例min

从事嵌入式linux android驱动开发,拥有全栈能力 311

【TC3xx芯片】TC3xx芯片STM介绍

TC3xx芯片STM介绍

qq_36056498的博客 2280

HDU 5950 Recursive sequence 递推转矩阵【矩阵快速幂】

题解翻译转自此处 题意 f[n]=f[n-1]+2f[n-2]+n^4; f[1]=a f[2]=b 求第n项 解析 直接递推肯定会超时的 所以 构造一个77系数矩阵 直接快速幂解出来 由于现在比较菜 只会最简单的矩阵 勉强可以写出来。。。。 1 2 1 0 0 0 0    f[i-1]        f[i] 1 0 0 0 0 0 0    f[...

HEATHEN__的博客 189

Win11极速安装Tensorflow-gpu+CUDA+cudnn(含视频)

Win11极速安装Tensorflow-gpu+CUDA+cudnn(含视频链接)

weixin_46713695的博客 1万+

递推关系转矩阵快速幂

一些递推关系如f(n) = af(n-1)+bf(n-2)+...+tf(n-k)等,在n很大的时候,O(n)的算法都不能满足要求的时候,往往可以化为矩阵快速幂来做,复杂度可以降为O(logn),大大减少了运行时间。 如何将一个递推关系式化为矩阵呢? 比如这样一个递推关系: f(n) = 2*f(n-1)+4*f(n-2) 先列出几个等式: f(n) =2*f(n-1)+4*f...

weixin_30363817的博客 248

Marvell 88Q6113 如何制作一个完整的量产固件88Q6113_flash.bin并进行烧录

本章节介绍如何基于Marvell工具链,制作一个完整的量产固件88Q6113_flash.bin,集成用户自定义的配置文件 config.bin,用于88Q6113的Flash烧录。注:Marvell 88Q5072 与 Marvell 88Q6113 的配置流程是一样的。

老板来份猪脚拼叉烧的博客 2009

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

快速幂取模算法【转】

转自:http://blog.youkuaiyun.com/lsldd/article/details/5506933 参考文章来源:Reait Home(http://www.reait.com/blog.html) 转载请注明,谢谢合作。 在Miller Rabbin测试素数,就用到了快速幂取模的思想。这里总结下。求a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求...

weixin_30237281的博客 92

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[转]快速幂(C语言实现) 超详细

快速幂取模算法在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C语言,不同语言的读者只好换个位啦,毕竟读C的人较多~所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。[有读者反映在讲快速幂部分时有点含糊,所以

kker的博客 4464

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

整数快速乘法/快速幂+矩阵快速幂+Strassen算法 (转)

整数快速乘法/快速幂+矩阵快速幂+Strassen算法 快速幂算法可以说是ACM一类竞赛中必不可少,并且也是非常基础的一类算法,鉴于我一直学的比较零散,所以今天用这个帖子总结一下 快速乘法通常有两类应用:一、整数的运算,计算(a*b) mod c 二、矩阵快速乘法 一、整数运算:(快速乘法、快速幂) 先说明一下基本的数学常识: (a*b) mod c == ( (a mo...

weixin_30563917的博客 423

【转】C语言快速幂取模算法小结

(转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法。分享给大家供大家参考之用。具体如下: 首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。我们先从简单的...

weixin_30539835的博客 135

HDU5015_233 Matrix(矩阵快速幂,递推转矩阵)

题意: 给定矩阵的第一行和第一列,其余每项a[i][j]=a[i−1][j]+a[i][j−1]a[i][j] = a[i-1][j] + a[i][j-1]a[i][j]=a[i−1][j]+a[i][j−1],求an,m%10000007a_{n,m}\% 10000007an,m​%10000007 数据范围: n<=10,m<=109,0<=a1,0,a2,0,...,a...

YunTunLu的博客 249

26.1.3 快速幂+容斥 树上dp+快速幂 带前缀和的快速幂 正序转倒序 子序列自动机 线段树维护滑窗

个数的前缀和,枚举所有前缀,对于一个前缀,计算出,可以和他形成合法区间的另一个前缀,前缀和应该是多少,去数据结构查询这个前缀和值的最大长度,即可得到以当前前缀结尾,为右端点的最短合法区间。现在问能否不匹配上,仍然考虑把t作为自动机,s作为输入串,匹配不上就是扫完s,没转移到t的终态,我们能构造t,那贪心的想,就要通过构造,让t的转移尽量慢,也就是,直到s里。的值,我们现在关心进行的操作次数,那么对其优化显然就是优化成辗转相除,每次较大的对较小的取模,即可直接跳过一段相同的减法操作,有解的话,最后应该是。

Maxwell_Newton的博客 824

快速幂算法

之和的形式,因为这样可以不断的将之前算过的数复用。现在读者是不是恍然大悟?这也是为什么我们在讲快速幂之前需要铺垫十进制转二进制的原因。我们有很多种拆法,但在快速幂算法中,我们往往采用将幂拆成。算法.但在介绍快速幂的算法之前,我们来看看。为了能够将这类题目进一步优化,我们就有了。在上述进制转化中,我们将任意数拆成。

qq_60805019的博客 212

CH3401 二维转一维矩阵+转移矩阵分析+矩阵快速幂

CH3401 二维转一维矩阵+转移矩阵分析+矩阵快速幂 题面 CH3401 题面 思路 由于t有可能很大很大,直接模拟是不现实的,这种操作用矩阵表示的问题,明显要用矩阵快速幂解决,但是有以下几个难点: 如何用矩阵操作二维矩阵中的每一个数 如何构造对应的转移矩阵 如何寻找循环节 解决本题随着这三个问题的解决就迎刃而解: 一开始寻找如何操作二维矩阵中的每一个数,但是发现初等变换都是动一个数就至少...

Time Limit Exceeded on test 99 753
上一篇: 分数规划
下一篇: poj2367
NeighThorn
博客等级 码龄11年 20粉丝 171原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值