快速幂
快速幂
递归快速幂
递归
无非是一个二分的思路。我们很自然地可以得到一个递归方程:
计算a的n次方,如果n是偶数(不为0),那么就先计算a的n/2次方,然后平方;如果n是奇数,那么就先计算a的n-1次方,再乘上a;递归出口是a的0次方为1。
int qpow(int a, int n)
{
if (n == 0)
return 1;
else if (n & 2 == 1)
return qpow(a, n - 1) * a;
else
{
int temp = qpow(a, n / 2);
return temp * temp;
}
}
在实际问题中,题目常常会要求对一个大数取模,这是因为计算结果可能会非常巨大,但是在这里考察高精度又没有必要。这时我们的快速幂也应当进行取模,此时应当注意,原则是步步取模,如果MOD较大,还应当开long long。
static int num;
int qpow(int a, int n)
{
if (n == 0)
return 1;
else if (n & 2 == 1)
return qpow(a, n - 1) * a%num;
else
{
int temp = qpow(a, n / 2)%num;
return temp * temp%num;
}
}
大家知道,递归虽然简洁,但会产生额外的空间开销。我们可以把递归改写为循环,来避免对栈空间的大量占用,也就是非递归快速幂。
非递归
我们换一个角度来引入非递归的快速幂。还是7的10次方,但这次,我们把10写成二进制的形式,也就是
现在我们要计算
//非递归快速幂
static long powMod(long a, int b) {
long ret = 1;
while (b != 0) {
if ((b & 1) == 1)
ret *= a;
b >>= 1;
a = a * a;
}
return ret;
}
这里的位运算符,>>是右移,表示把二进制数往右移一位,相当于/2;
取模版本的
static long powMod(long a, int b, final long mod) {
long ret = 1;
while (b != 0) {
if ((b & 1) == 1)
ret = ret * a % mod;
b >>= 1;
a = a * a % mod;
}
return ret % mod;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)