- Python
C++ 快速幂教程
- 2025-5-3 12:17:52 @
📌 什么是快速幂?
快速幂(Exponentiation by squaring) 是一种高效计算一个数的幂的方法。
相比于普通的循环乘法 a^b = a * a * ... * a
(共 b 次),快速幂的时间复杂度为 O(log b),特别适合处理大指数的情况。
✅ 学习目标
- 理解快速幂的基本思想
- 掌握如何用 C++ 实现快速幂算法
- 学会使用取模运算进行“模幂”运算(用于加密、竞赛等场景)
- 提供完整代码和详细注释
🧠 快速幂原理讲解
我们以求 为例:
核心思想:
将指数 分解成二进制形式,并利用平方操作减少乘法次数。
例如:$ a^{13} = a^{(8 + 4 + 1)} = a^8 \times a^4 \times a^1 $
我们可以不断将底数平方,同时判断当前位是否在二进制中为 1,如果是就乘到结果中。
🔢 基础版本:不带取模的快速幂
#include <iostream>
using namespace std;
// 快速幂函数(不取模)
long long fastPower(long long base, long long exponent) {
long long result = 1; // 初始化结果为1
while (exponent > 0) { // 当指数大于0时继续循环
if (exponent % 2 == 1) { // 如果当前指数是奇数(即二进制最后一位是1)
result = result * base; // 就把当前底数乘入结果
}
base = base * base; // 底数平方(相当于指数翻倍)
exponent = exponent / 2; // 指数除以2(右移一位)
}
return result;
}
int main() {
long long a = 2; // 底数
long long b = 10; // 指数
cout << a << "^" << b << " = " << fastPower(a, b) << endl;
return 0;
}
📌 输出示例:
2^10 = 1024
🔐 进阶版本:带取模的快速幂(模幂)
这是在密码学、算法竞赛中最常用的形式:计算
#include <iostream>
using namespace std;
// 快速幂取模函数
long long fastPowerMod(long long base, long long exponent, long long mod) {
long long result = 1; // 结果初始化为1
base = base % mod; // 先对底数取模,防止初始值过大
while (exponent > 0) {
if (exponent % 2 == 1) { // 如果当前指数是奇数
result = (result * base) % mod; // 把当前底数乘入结果并取模
}
base = (base * base) % mod; // 底数平方并取模
exponent = exponent / 2; // 指数除以2
}
return result;
}
int main() {
long long a = 2; // 底数
long long b = 10; // 指数
long long m = 1000; // 模数
cout << a << "^" << b << " mod " << m << " = " << fastPowerMod(a, b, m) << endl;
return 0;
}
📌 输出示例:
2^10 mod 1000 = 24
📚 补充说明
参数名 | 含义 |
---|---|
base |
底数,即 a |
exponent |
指数,即 b |
mod |
取模值,可选 |
💡 使用场景推荐
场景 | 是否需要取模 |
---|---|
计算非常大的幂 | ✅ 是(否则可能溢出) |
密码学(如 RSA 加密) | ✅ 是 |
算法竞赛(如 ACM、蓝桥杯) | |
小规模幂运算 | ❌ 否 |
⚠️ 注意事项
- 数据类型选择:建议使用
long long
防止中间结果溢出。 - 负指数问题:本教程不涉及负指数,若需要支持请加条件判断。
- 浮点数快速幂:也可实现浮点数幂运算,但需注意精度问题。
📝 总结
- 快速幂是一个非常高效的幂运算方法。
- 时间复杂度:O(log b),比 O(b) 快很多。
- 在实际编程中,尤其是算法竞赛和密码学中,模幂运算尤为重要。
- 推荐将模幂函数写成模板或封装成工具类函数,在多个项目中复用。
3 条评论
-
admin SU @ 2025-5-3 12:25:07
用递归的方式实现快速幂算法
下面为你详细介绍如何用递归方式实现快速幂算法,同时给出相应的代码及解释。
递归思路
递归实现快速幂算法的核心在于依据指数的奇偶性来分情况处理:
- 当指数
n
为偶数时, 可转化为 。 - 当指数
n
为奇数时, 可转化为 。
代码实现
下面是使用 C++ 实现的递归快速幂算法,代码中添加了详细注释:
#include <iostream> // 递归实现快速幂函数,计算 a 的 n 次幂 long long recursiveFastPower(long long a, long long n) { // 若指数为 0,任何数的 0 次幂都为 1 if (n == 0) { return 1; } // 若指数为偶数 if (n % 2 == 0) { // 先计算 a 的 n/2 次幂 long long temp = recursiveFastPower(a, n / 2); // 再将结果平方 return temp * temp; } else { // 若指数为奇数,先计算 a 的 n - 1 次幂,再乘以 a return a * recursiveFastPower(a, n - 1); } } int main() { long long a = 2; // 底数 long long n = 13; // 指数 // 调用递归快速幂函数计算结果 long long result = recursiveFastPower(a, n); // 输出结果 std::cout << a << " 的 " << n << " 次幂是: " << result << std::endl; return 0; }
代码解释
- 函数定义:
recursiveFastPower
函数接收两个参数a
和n
,分别代表底数和指数,返回值为 的结果。 - 基准情况:当
n
为 0 时,函数直接返回 1,因为任何数的 0 次幂都是 1。 - 指数为偶数的情况:若
n
为偶数,先递归计算 的结果存储在temp
中,再将temp
平方得到最终结果。 - 指数为奇数的情况:若
n
为奇数,先递归计算 的结果,再乘以a
得到最终结果。 - 主函数:在
main
函数里,设定底数a
和指数n
,调用recursiveFastPower
函数计算结果并输出。
复杂度分析
- 时间复杂度:,由于每次递归时指数要么减半,要么减 1,所以递归深度为 。
- 空间复杂度:,递归调用栈的深度为 。
- 当指数
-
2025-5-3 12:24:13@
快速幂算法简介
快速幂是一种高效计算幂运算的算法。通常,计算 时,普通的方法是将 连乘 次,时间复杂度为 。而快速幂算法可以将时间复杂度降低到 ,大大提高了计算效率,尤其是当 非常大的时候。
原理
快速幂算法的核心思想是利用指数的二进制表示。例如,要计算 ,因为 的二进制表示是 ,即 ,那么 $a^{13} = a^{2^3 + 2^2 + 2^0} = a^{2^3} \times a^{2^2} \times a^{2^0}$。
代码实现
下面是一个用C++实现的快速幂算法的示例代码,包含详细的注释:
#include <iostream> // 快速幂函数,计算 a 的 n 次幂 long long fastPower(long long a, long long n) { long long result = 1; // 初始化结果为 1 long long base = a; // 初始化底数为 a // 当指数 n 大于 0 时,继续循环 while (n > 0) { // 如果 n 的二进制表示的最低位是 1 if (n % 2 == 1) { result *= base; // 将当前的底数乘到结果中 } base *= base; // 底数平方 n /= 2; // 指数右移一位 } return result; } int main() { long long a = 2; // 底数 long long n = 13; // 指数 // 调用快速幂函数计算结果 long long result = fastPower(a, n); // 输出结果 std::cout << a << " 的 " << n << " 次幂是: " << result << std::endl; return 0; }
代码解释
- 函数定义:
fastPower
函数接受两个参数a
和n
,分别表示底数和指数,返回值为 的结果。 - 初始化:
result
初始化为 1,用于存储最终结果;base
初始化为a
,表示当前的底数。 - 循环条件:
while (n > 0)
表示只要指数n
大于 0,就继续循环。 - 判断最低位:
if (n % 2 == 1)
用于判断n
的二进制表示的最低位是否为 1,如果是 1,则将当前的底数base
乘到结果result
中。 - 底数平方:
base *= base
表示将底数平方,相当于将指数翻倍。 - 指数右移:
n /= 2
表示将指数右移一位,相当于去掉二进制表示的最低位。 - 返回结果:循环结束后,返回最终的结果
result
。
复杂度分析
- 时间复杂度:,因为每次循环指数都会减半。
- 空间复杂度:,只使用了常数级的额外空间。
通过这种方式,你可以高效地计算幂运算,尤其是在处理大规模数据时,快速幂算法的优势会更加明显。
- 函数定义:
-
2025-5-3 12:18:17@
快速幂是一种高效计算幂次的算法,它可以将计算 的时间复杂度从朴素算法的 降低到 。下面为你详细介绍快速幂算法的原理和实现,以及如何在 C++ 中实现它。
原理
快速幂算法的核心思想是利用幂次的二进制分解。假设我们要计算 ,可以将 表示为二进制形式,例如:。那么 就可以写成 $a^{2^k_1}\times a^{2^k_2}\times\cdots\times a^{2^k_m}$。
例如,计算 ,因为 的二进制表示是 ,即 ,所以 。
代码实现
以下是使用 C++ 实现快速幂的代码:
#include <iostream> // 快速幂函数 long long fastPower(long long a, long long n) { long long result = 1; while (n > 0) { if (n & 1) { // 判断 n 的二进制最后一位是否为 1 result *= a; } a *= a; // a 平方 n >>= 1; // n 右移一位,相当于除以 2 } return result; } int main() { long long a = 2; long long n = 13; long long ans = fastPower(a, n); std::cout << a << " 的 " << n << " 次幂是: " << ans << std::endl; return 0; }
代码解释
- 初始化结果:
result
初始化为 1,用于存储最终结果。 - 循环条件:当
n > 0
时,继续循环。 - 判断二进制最后一位:使用
n & 1
判断n
的二进制最后一位是否为 1,如果是 1,则将当前的a
乘到result
中。 - 平方操作:将
a
平方,即a *= a
。 - 右移操作:将
n
右移一位,相当于将n
除以 2。 - 返回结果:当
n
变为 0 时,循环结束,返回result
。
复杂度分析
- 时间复杂度:,因为每次循环
n
都会减半。 - 空间复杂度:,只使用了常数级的额外空间。
取模运算
在实际应用中,幂次的结果可能会非常大,为了避免溢出,通常会对结果取模。以下是带有取模运算的快速幂代码:
#include <iostream> const long long MOD = 1e9 + 7; // 带取模的快速幂函数 long long fastPowerMod(long long a, long long n) { long long result = 1; a %= MOD; // 防止 a 过大 while (n > 0) { if (n & 1) { result = (result * a) % MOD; } a = (a * a) % MOD; n >>= 1; } return result; } int main() { long long a = 2; long long n = 13; long long ans = fastPowerMod(a, n); std::cout << a << " 的 " << n << " 次幂对 " << MOD << " 取模的结果是: " << ans << std::endl; return 0; }
这个代码在每次乘法操作后都对结果取模,确保结果不会溢出。
- 初始化结果:
- 1