【问题标题】:Calculate the modulus of a big sum [closed]计算大和的模数[关闭]
【发布时间】:2017-01-12 09:13:31
【问题描述】:

我需要计算

 1^2 + 2^2 + ... + n^2 modulo 10234573 

n 最高 20 亿。我需要使用原生 C++ 库。我不知道该怎么做,因为这似乎是一个巨大的数字。

【问题讨论】:

  • 带符号的 32 位整数的范围从负二十亿到正二十亿。所以在这里使用普通的int 没问题。 This table of value ranges 你可能会感兴趣。
  • 这其实挺有意思的。为什么不研究呢?
  • 这不可能是一个巨大的数字 - 根据定义,它必须小于 10234573。提示:(a+b) % n == ((a%n) + (b%n) %n)x² % n == (x%n)² % n,因此您只需要处理最大为 10234573² 的数字。

标签: c++ algorithm modulo


【解决方案1】:

您可以通过归纳轻松证明

 1 + 4 + 9 + 16 + ... + k**2 + ... + n**2 == n * (n + 1) * (2 * n + 1) / 6

http://oeis.org/A000330

唯一的困难是你必须除以6,并且由于总和是一个整数值,你必须考虑6的情况(每个可能的n mod 6结果):

int SumOfSquares(int n) {
  int64_t modulo = 10234573;

  int64_t a = n;
  int64_t b = a + 1;     /* even n+1 can exceed the limit; let's change n to a */
  int64_t c = 2 * a + 1; /* 2*n can exceed the limit; let's change n to a */

  switch (n % 6) {
    case 0:
      a /= 6;
      break;
    case 1:
      b /= 2;
      c /= 3;
      break;
    case 2:
      a /= 2;
      b /= 3;
      break;
    case 3:
      a /= 3;
      b /= 2;
      break;
    case 4:
      a /= 2;
      c /= 3;
      break;
    case 5:
      b /= 6;
      break;
  }

  /* combersome to ensure we are in [0..modulo ** 2] range */
  return (int) (((((a % modulo) * (b % modulo)) % modulo) * (c % modulo)) % modulo);
}  

我们可能会得到一个高达 (modulo - 1) ** 2 == 104746484492329 的因子,因为这超出了最大可能的 32 位整数值 (2147483647),我们必须使用 int64_t 作为因子。

int result = SumOfSquares(2000000000); /* result == 986488 */

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 2012-01-15
    相关资源
    最近更新 更多