📜  模数10 ^ 9 + 7(1000000007)(1)

📅  最后修改于: 2023-12-03 15:26:51.421000             🧑  作者: Mango

模数 10^9+7

在计算机程序中,经常需要对防止数字过大而进行取模操作。一种常用的模数是 10^9+7,即1000000007。

为什么使用 10^9+7 作为模数?

使用 $10^9+7$ 作为模数有很多好处:

  • 这是一个质数,使用质数作为模数可以确保结果唯一。
  • $10^9+7$ 不是一个特别大的数,可以用 int 类型存储。 使用 int 类型可以优化程序的速度和内存占用。
  • 这个质数有一个特定的性质,即它的二进制表示中有很多0,1的组合,这使得它成为一些算法的最佳选择,例如快速幂算法。
如何通过 10^9+7 计算模数?

在计算中,常常需要使用到以下两种操作:

  • 加法取模
  • 乘法取模
加法取模

两个数相加后取模可以写成 $(a + b) \mod M$。使用本题的模数 10^9+7,应该使用以下代码实现加法取模:

int add_mod(int a, int b, int M) {
    int res = (a + b) % M;
    if(res < 0) res += M;
    return res;
}
乘法取模

两个数相乘后取模可以写成 $(a*b) \mod M$。使用本题的模数 10^9+7,应该使用以下代码实现乘法取模:

int mul_mod(int a, int b, int M) {
    return (int)(((long long)a * b) % M);
}

上述代码使用 long long 类型的变量避免了在计算过程中数值超过 int 范围的问题。

如何实现快速幂?

快速幂算法是一种用于快速计算 $x^y$的算法,通过反复平方法可以将时间复杂度从 $O(y)$ 优化到 $O(\log y)$。在计算模数时,应该使用快速幂算法在 $O(\log y)$ 的时间内计算结果。

使用本题的模数 10^9+7,应该使用以下代码实现快速幂:

int pow_mod(int x, int y, int M) {
    int res = 1;
    while(y) {
        if(y & 1) res = mul_mod(res, x, M);
        x = mul_mod(x, x, M);
        y >>= 1;
    }
    return res;
}

上述代码中 & 表示按位与运算,不重要于本题,请自行了解。上述代码中使用了 mul_mod 函数计算乘法取模,使用了右移运算符 >> 表示除以2的整除。

如何处理取模前的负数?

在进行加法取模和乘法取模时,有可能得到结果为负数。为了与其他语言的实现相兼容,应该将这些负数转为非负数。转换方法如下:

if(res < 0) res += M;
如何保证程序的正确性?

在使用模数计算时,应该始终注意下列事项:

  • 在数值过大时一定要使用 long long 类型。
  • 在计算过程中经常需要进行取模,一定要始终保证数值是非负的。
  • 在自行实现计算函数时,务必使用 unsigned long long 类型。这可以保证在计算过程中得到正确的结果。
  • 在计算时,务必使用 10^9+7 作为模数。
参考链接