【问题标题】:C++ : How to calculate modulo of a number raised to large power?C++:如何计算一个大幂数的模?
【发布时间】:2018-04-07 14:59:30
【问题描述】:

我正在解决一个编程问题,我必须以 answer mod 10 ^ 9 + 7 格式打印答案,其中“答案”是问题的实际答案。

我已经找到了解决问题的算法,但需要注意的是,问题的答案始终采用 m * 10 ^ n 格式,其中

1

接下来我该怎么做?

【问题讨论】:

标签: c++ algorithm number-theory mod


【解决方案1】:

评估10^n mod M

您需要的是Modular Exponentiation。它可以计算(a^b)%m in log_2(b)(log base 2)。

示例

假设您需要计算10^9

  1. 一种方法是按顺序多次109
  2. 或者,使用分而治之的方法。

    10^9 = (10^8)*(10^1)

    10^8 = (10^4)*(10^4) : 你需要计算10^4 两次吗?

    10^4 = (10^2)*(10^2) : 你需要计算10^2 两次吗?

    10^2 = (10^1)*(10^1)

    10^1 = (10^1)*(10^0)

    10^0 是基本情况。

    所以,我们基本上做的是:

    1. 如果power 是奇数,那么我们计算base^(power-1) 并将其与base 相乘得到base^power。 [base^power = (base^(power-1)) * base)]
    2. 如果power 是偶数,那么我们计算base^(power/2) 并将其与自身相乘得到base^power。 [base^power = (base^(power/2)) * (base^(power/2))]。但是我们只计算一次base^(power/2)

计算复杂度

here所述:

简要分析表明,这样的算法使用floor(log_2(n))平方和 最多floor(log_2(n)) 乘法。更准确地说, 乘法的数量比存在的数量少一 在 n 的二元展开中。

所以,我们可以说运行时的顺序是log_2(n)。 (O(log_2(power)))

求模部分:

很容易注意到,在计算像 10^(10^18) 这样大的值时,我们势必会溢出最大的原始类型 (long long int)。而这里输入Modular Multiplication,据此(a * b) % c = ((a % c) * (b % c)) % c。附带说明一下,当您直接查看代码时,您可能看不到此规则正在使用中,但如果您评估递归调用,则会使用它。

问题解决了吗?

我们通过在运行时计算模数来防止溢出。比如说,如果我们得到一些值作为10^9,我们需要将它与自身相乘。溢出?不,这次不是。

ans = ((10^9 % 1000000007) * (10^9 % 1000000007)) % 1000000007
ans = 10^18 % 1000000007
ans = 49

代码:

虽然有多种实现,这里有一个简单的:

const int M = 1e9 + 7;
long long int powxy(long long int x, long long int y) {
    if (y == 0) return 1;
    if (y%2 == 1) return (x*powxy(x, y-1))%M;
    long long int t = powxy(x, y/2);
    return (t*t)%M;
}

测试here

【讨论】:

  • 这太棒了。非常感谢 :) PS:这个问题我得了满分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2012-07-06
  • 2017-04-03
  • 2023-03-30
相关资源
最近更新 更多