该函数 qpow
实现了快速幂算法(Fast Exponentiation) ,用于高效计算幂运算 <math xmlns="http://www.w3.org/1998/Math/MathML"> x n x^n </math>xnmod MOD的结果(其中 MOD
是一个全局常量)。以下是详细说明:
功能:
计算 x 的 n 次幂,并对全局常量取模,即返回 <math xmlns="http://www.w3.org/1998/Math/MathML"> x n x^n </math>xnmod MOD的值。
算法原理:
-
二进制分解指数 n : 将指数 n 视为二进制形式(例如 n =13 的二进制为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 110 1 2 = 8 + 4 + 1 1101_2=8+4+1 </math>11012=8+4+1),则:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> x n = x 2 k 1 + 2 k 2 + ⋯ = x 2 k 1 × x 2 k 2 × ⋯ x^n=x^{2^{k_1}+2^{k_2}+⋯}=x^{2^{k_1}} \times x^{2^{k_2}} \times \cdots </math>xn=x2k1+2k2+⋯=x2k1×x2k2×⋯
-
平方迭代 : 通过循环反复平方 x (即 x ← <math xmlns="http://www.w3.org/1998/Math/MathML"> x 2 x^2 </math>x2 mod MOD),生成的 <math xmlns="http://www.w3.org/1998/Math/MathML"> x 1 , x 2 , x 4 , x 8 , . . . x^1,x^2,x^4,x^8,... </math>x1,x2,x4,x8,...的序列。
-
按位累积结果 : 遍历 n 的二进制位。若某位为1,则将当前的 x 累积到结果
res
中。
代码解析:
c++
long long qpow(long long x, int n) {
long long res = 1; // 初始化结果为 1
while (n) { // 当指数 n 未处理完时循环
if (n & 1) { // 检查 n 的最低位是否为 1
res = res * x % MOD; // 若为 1,累积当前 x 到结果(取模)
}
x = x * x % MOD; // 平方迭代:x = x^2 mod MOD
n >>= 1; // 右移一位(等价于 n /= 2)
}
return res; // 返回最终结果
}
示例:
以 x=2,n=13,MOD=1000 为例:
- 初始化 :
res = 1
,x = 2
,n = 13 (二进制 1101)
. - 循环步骤 :
- 迭代 1:
n & 1 = 1
→res = 1 * 2 % 1000 = 2
x = 2^2 % 1000 = 4
,n = 6 (二进制 110)
. - 迭代 2:
n & 1 = 0
→ 不更新res
x = 4^2 % 1000 = 16
,n = 3 (二进制 11)
. - 迭代 3:
n & 1 = 1
→res = 2 * 16 % 1000 = 32
x = 16^2 % 1000 = 256
,n = 1 (二进制 1)
. - 迭代 4:
n & 1 = 1
→res = 32 * 256 % 1000 = 8192 % 1000 = 192
x = 256^2 % 1000 = 65536 % 1000 = 536
,n = 0
.
- 迭代 1:
- 返回结果 :
res = 192
(即 <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 13 m o d 1000 = 8192 m o d 1000 = 192 2^{13} mod 1000 = 8192 mod 1000=192 </math>213mod 1000=8192mod 1000=192)。
关键点:
- 时间复杂度 :O (logn ),远优于朴素循环 O (n)。
- 模运算优化:每一步乘法和平方后立即取模,避免溢出。
- 适用场景:大数幂运算(如密码学、组合数学中常见的模幂计算)。
- 注意事项 :
- 假设
MOD
是全局定义的常量。 - 指数 n 必须为非负整数(负数会导致死循环)。
- 假设