快速幂
2021-10-20 09:09:16 40 举报
AI智能生成
快速幂
作者其他创作
大纲/内容
快速幂(Exponentiation by squaring,平方求幂)是一种简单而有效的小算法,它可以以[公式]的时间复杂度计算乘方。<br>
思考<br>
7的10次方,怎样算比较快?
方法1:最朴素的想法,7*7=49,49*7=343,... 一步一步算,共进行了<font color="#ff0000">9次乘法</font>。
方法2:先算7的5次方,即7*7*7*7*7,再算它的平方,共进行了<font color="#ff0000">5次乘法</font>。
方法3:先算7*7得49,则7的5次方为49*49*7,再算它的平方,共进行了<font color="#ff0000">4次乘法</font>。
实现
递归快速幂
思路
二分法,可以得到一个递归方程:
计算a的n次方:<br><ul><li>如果n是偶数(不为0),那么就先计算a的n/2次方,然后平方;</li><li>如果n是奇数,那么就先计算a的n-1次方,再乘上a;</li><li>递归出口是a的0次方为1。</li></ul>
实现
//递归快速幂<br>int qpow(int a, int n)<br>{<br> if (n == 0)<br> return 1;<br> else if (n % 2 == 1)<br> return qpow(a, n - 1) * a;<br> else<br> {<br> //这个temp变量是必要的, 不然的话会导致整个算法就退化为O(n)<br> int temp = qpow(a, n / 2);<br> return temp * temp;<br> }<br>}<br>
优化
递归虽然简洁,但会产生额外的空间开销。
非递归快速幂
思路
我们把10写成二进制的形式,也就是 (1010)。
现在我们要计算 (1010) ,可以怎么做?
我们很自然地想到可以把它拆分为(1000)+(10)
实际上,对于任意的整数,我们都可以把它拆成若干个(10....)的形式相乘。
7^(1000) 、7^(10)恰好就是7^8、 7^2, 我们只需<font color="#ff0000">不断把底数平方</font>就可以算出它们。
实现
//非递归快速幂<br>int qpow(int a, int n){<br> int ans = 1;<br> while(n){<br> //如果n的当前末位为1<br> if(n&1){<br> //ans乘上当前的a <br> ans *= a; <br> }<br> //a自乘<br> a *= a; <br> //n往右移一位 <br> n >>= 1; <br> }<br> return ans;<br>}<br>
应用
模意义下取幂: 计算 x^k % n.
取模的运算不会干涉乘法运算,因此我们只需要在计算的过程中取模即可
实现
//非递归快速幂<br>int qpow(int a, int n, int mod){<br> int ans = 1;<br> while(n){<br> //如果n的当前末位为1<br> if(n&1){<br> //ans乘上当前的a并取模 <br> ans = ans * a % mod; <br> }<br> //a自乘并取模<br> a = a * a % mod; <br> //n往右移一位 <br> n >>= 1; <br> }<br> return ans;<br>}<br>
0 条评论
下一页