[算法]快速幂
(基本上是从百度百科搬过来的,虽然本大佬是宇宙无敌牛逼,但是有错还请指出~谢谢,有空请你一起抠脚~么么哒)
求底数为a的n次幂:
一般解法都是“a*a*a……*a”,复杂度为O(n);
下面是快速幂解法:
1.把n转换为二进制,例如:
11转换为二进制1011;
2.将n得到的二进制以“数位的值*权值”的和表示,例如:
11可表示为“1*(2^3)+0*(2^2)+1*(2^1)+1*(2^0)”;
3.由第2点可以得到a的11次方为:
a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0));
那么就可得以下代码(下面的代码将结果取模了,因为一般的运算结果过于庞大,题目或者实际都是要求是将结果取模,如果不需要取模自行删除即可),时间复杂度是O(log2n):
1 #include<iostream> 2 using namespace std; 3 int main()//计算a^n % mod 4 { 5 long long a, n, mod; 6 long long re = 1; 7 cin>>a>>n; 8 while(n) 9 { 10 if(n & 1){//判断n的最后一位是否为1 11 re = (re * a) % mod; 12 } 13 n >>= 1;//移位操作,去掉n的最后一位 14 a = (a * a) % mod; 15 /*这里用了一个技巧,a*a即求出了a^(2^(i-1)) 16 *不知道这是什么的看原理 17 *a^(2^(i-1))*a^(2^(i-1))=a^(2^i) 18 *而且一般情况下a*b mod c =(a mod c)*(b mod c) mod c*/ 19 } 20 cout<< re % mod; 21 return 0; 22 }
需要注意的是,可能很多人都看不懂14行的含义:
a = (a * a) % mod;
不理解的话就只能是生搬硬套的模板,没有任何意义。虽然代码注释里都说了,但是还是得讲一下自己的理解,我也怕以后忘记了,还是以a的11次方为例:
由于n的二进制的数位的值只会是1和0,因此上面第3点得到的式子中的1省去,有:
a^(1*(2^3))*a^(0*(2^2))*a^(1*(2^1))*a^(1*(2^0)) => a^(2^3) * a^(0*(2^2)) * a^(2^1) * a^(2^0)
看到上式2的指数,那么注释里的 “ a^(2^(i-1))*a^(2^(i-1))=a^(2^i) ” 是不是就清晰易懂了呢?
至于递归的代码,这里就不给了,百度百科里面都有,感谢亲亲看完哟~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现