【单选】执行 power(2, 100, 1000) 调用下列函数,返回值是( )。
long long power(long long a, long long b, long long p) {
long long r = 1 % p;
while (b) {
if (b & 1)
r = r * a % p;
a = a * a % p;
b >>= 1;
}
return r;
}这是快速幂(模幂)的模板:求 2^100 mod 1000。要么按二进制逐位平方-乘手算,要么直接注意到 2^100 的末三位是 376。
把 r = 1 % p 忽略而算错起点;中间值 a = a * a % p 忘记取模导致越界(虽然 long long 不会溢出,但手算时要记得每步取模)。
题目函数:
long long power(long long a, long long b, long long p) {
long long r = 1 % p;
while (b) {
if (b & 1) r = r * a % p; // 该位为 1 → 把当前的 a 乘进答案
a = a * a % p; // 底数平方,为下一位做准备
b >>= 1; // 指数右移一位
}
return r;
}求 power(2, 100, 1000) = 2^100 mod 1000。
100 = 1100100₂(位权:64 + 32 + 4 = 100 ✓)。按位从低到高处理:
| 位 | b 的最低位 | 动作 | r | a |
|---|---|---|---|---|
| — | — | 初值 | 1 | 2 |
| 1 | 0 | 只平方 | 1 | 2²=4 |
| 2 | 0 | 只平方 | 1 | 4²=16 |
| 3 | 1 | r ← r×a;再平方 | 16 | 16²=256 |
| 4 | 0 | 只平方 | 16 | 256²=65536 ≡ 536 |
| 5 | 0 | 只平方 | 16 | 536²=287296 ≡ 296 |
| 6 | 1 | r ← r×a;再平方 | 16×296=4736 ≡ 736 | 296²=87616 ≡ 616 |
| 7 | 1 | r ← r×a | 736×616=453376 ≡ 376 | (结束) |
结果 376,选 B。
注意 2^100 = (2^10)^10 = 1024^10。
2^10 = 1024 → 末三位 024;2^20 = 1048576 → 576;2^30 → 576×576 = 331776 → 776……末三位会快速稳定:2^n (n ≥ 3) 的末三位以 100 为周期,而 2^100 的末三位正是 376(也是 2^100 的十进制末三位,100 = 4×25 的经典结论)。
r = 1 % p 是防 p = 1 的写法,读程序题要能看出这个小细节;