📜  二进制取幂模 m - C++ (1)

📅  最后修改于: 2023-12-03 14:49:02.005000             🧑  作者: Mango

二进制取幂模 m - C++

在计算机科学中,二进制取幂模 m 是一个经常使用的算法。 它可以有效地计算某个数字的指数值模 m 的结果,可以避免使用大数运算而遭受的运算效率问题。

本文将介绍二进制取幂模m的基本概念及其在C++中的实现。

二进制取幂模m的基本概念

假设有$a$和$b$是两个整数,可以使用二进制方法来高效计算$a^b$取模$m$的结果。这个算法基于以下事实:

  • 对于任意正整数$x$和$y$,有$x^y=x^{y/2}\times x^{y/2}\times x^{y\bmod 2}$。
  • 对于任意正整数$x$和$y$,有$x^{y}\bmod m=((x^{y/2}\bmod m)\times (x^{y/2}\bmod m)\times (x^{y\bmod 2}\bmod m))\bmod m$。

这个算法的核心思想是将指数$b$表示为一个二进制数,然后从右往左依次计算出每一位的值。如果这一位的值为$1$,就将$a$乘上它的权值,否则权值不变。关键这里的权值是$a^2$。

算法说明如下:

  1. 将指数$b$表示为二进制数
  2. 计算出$a^2, a^4,a^8,...,a^{2^k}$的值,其中$k$是$b$的二进制长度
  3. 从右往左计算每一位的贡献,如果该位为$1$,将$a$乘以该位的权值,否则不变
  4. 累加这些贡献,最后取模$m$即为答案
C++实现

在C++中,可以使用以下代码来实现二进制取幂模m的算法:

long long modPow(long long a, long long b, long long m) {
    long long res = 1;
    while (b > 0) {
        if (b & 1) {
            res = (res * a) % m;
        }
        a = (a * a) % m;
        b >>= 1;
    }
    return res;
}

这个函数接受三个参数:一个整数$a$,一个正整数$b$,一个正整数$m$。函数返回$a^b\bmod m$的值。

该算法的时间复杂度为$O(\log b)$,其中$b$是指数的长度。这使得它在需要高效幂计算的场合非常有用。注意,此函数有些情况下可能需要使用大数运算库来避免溢出问题。

示例

以下示例展示了如何使用C++实现二进制取幂模m算法。

#include <iostream>
using namespace std;

long long modPow(long long a, long long b, long long m) {
    long long res = 1;
    while (b > 0) {
        if (b & 1) {
            res = (res * a) % m;
        }
        a = (a * a) % m;
        b >>= 1;
    }
    return res;
}

int main() {
    long long a = 2, b = 10, m = 1000000007;
    cout << modPow(a, b, m) << endl;  // 1024

    return 0;
}

上述程序返回$a^b\bmod m$的值,其中$a=2$,$b=10$,$m=10^9+7$。结果为$1024$。

总结

二进制取幂模m是一个非常有用的算法,可以高效计算指数取模问题。C++提供了非常方便的实现方式,可以方便地使用该算法来解决实际问题。