[算法]快速幂

(基本上是从百度百科搬过来的,虽然本大佬是宇宙无敌牛逼,但是有错还请指出~谢谢,有空请你一起抠脚~么么哒)

求底数为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) ” 是不是就清晰易懂了呢?

至于递归的代码,这里就不给了,百度百科里面都有,感谢亲亲看完哟~

 

posted @   小贼的自由  阅读(555)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示