快速幂(a^b%mod)
一、快速幂的作用
- 在求ab时,使用for循环一点一点求,就是幂运算的
O(b)
算法。 - 而使用快速幂求解,就是幂运算的
O(logb)
算法。
二、思路
- 引理:积的取余等于取余的积的取余。
- 思路:在以上引理的基础之上再对指数型数据进行拆分和合并从而得到快速幂算法。
三、快速幂具体分析
对于当a和b较小是直接用int或者long存是没有问题的,但是当a和b大到一定程度时,这就不是暴力存就可以解决的问题了。
说到底就是“大”的问题,所以我们要想办法不断地减小a和b的规模,所谓逐个击破。
引理,我们知道了可以把指数拆开:
//a是底数,b是指数,mode是取模数,sum是记录取模的结果
int sum = 1;
a = a % mode;
for(int i = 1; i <= b; i++)
{
sum = sum * a;
}
sum = sum % mode;
以上a的规模只被降低一次,我们可以进一步地降低a的规模,将其中的sum = sum * a
改成sum = (sum * a)%mode)
。
接着是降低b的规模,我们知道求解716可以将底数7两两合并,变成498,这样就把指数b的规模降低了,再利用上面的算法降低a的规模,多循环几次,就形成了快速幂算法。
但如果b为奇数,就无法两两合并,于是就在偶数的算法基础上,每次都先取出一个数,使其变为偶数。最终得出快速幂算法。
四、快速幂的代码
根据以上的分析,得出算法代码如下:
- 根据以2为模取余来判断奇偶性
long long Mode(long long a, long long b, long long mode)
{
long long sum = 1;
a = a % mode;
while (b > 0) {
if (b % 2 == 1) //判断是否是奇数,是奇数的话将多出来的数事先乘如sum
sum = (sum * a) % mode;
b /= 2;
a = (a * a) % mode;// 不断的两两合并再取模,减小a和b的规模
}
return sum;
}
-
根据&运算来判断奇偶性
&的操作符:二进制位中,1 & 1 = 1,其余组合均为0。
long long Mode(long long a, long long b, long long mode) { long long sum = 1; while (b) { if (b & 1) { sum = (sum * a) % mode; b--; } b /= 2; a = a * a % mode; } return sum; }
也可以将
b /= 2
换成位运算b >>= 1
。
参考资料:https://blog.csdn.net/qq_24016309/article/details/88585522
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY