快速幂
快速幂用于求解 \(a^b \bmod p\) 问题。
设 \(b\) 的二进制表示有 \(k\) 位,其中第 \(i \ (0\le i < k)\) 位为 \(c_i\),那么将 \(b\) 按照位权展开,于是:
\[b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+...+c_02^0
\]
那么:
\[a^b=a^{c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+...+c_02^0}=a^{c_{{k-1}}2^{k-1}}\times a^{c_{k-1}2^{k-2}} \times \dots \times a^{c_{0}2^{0}}
\]
又由于,\(c_{i}\) 要么为 \(0\) 要么为 \(1\),且:
\[a^{2^i}=(a^{2^{i-1}})^2
\]
再根据同余原理:
\[a^b \bmod p = ((a^{c_{{k-1}}2^{k-1}}) \bmod p\times (a^{c_{k-1}2^{k-2}}) \bmod p\times \dots \times (a^{c_{0}2^{0}}) \bmod p) \bmod p
\]
于是我们可以枚举 \(b\) 的二进制位 \(c_{i}\) 并按位取模,用变量维护 \(a^{2^{i}}\),当 \(c_{i}=1\),将 \(a^{2^{i}}\) 贡献到答案即可。
int qmi(int a, int b, int p) {
int res = 1;
a %= p;
while (b) {
if (b & 1) res = 1ll * res * a % p;
a = 1ll * a * a % p;
b >>= 1;
}
return res;
}

浙公网安备 33010602011771号