快速幂

快速幂用于求解 \(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;
}
posted @ 2026-02-13 14:57  uvwijk  阅读(3)  评论(0)    收藏  举报