【问题标题】:Overflow with power充满力量
【发布时间】:2016-01-01 13:12:06
【问题描述】:

如果我正在计算 [x*(a^b)%mod+y%mod]%mod,如果我只使用 (a^b)%mod,将它与 x 相乘会给我正确的答案吗?逐步计算 (x*(a^b))%mod 不是一个更好的主意吗?只是想向自己证明为什么不包括 x 作品。 可以做什么?

【问题讨论】:

  • A[i] 是整数吗?注意x * (2^y) == x << yy 是一个非负整数时。
  • 键入将 pow 转换为 long long。是的 A[i] 是一个整数,所以我会使用左移运算符,但仍然不会发生整数溢出?
  • 一般来说,在解决这类(竞争性编程)问题时,您永远不应该使用pow 函数。阅读:codeforces.com/blog/entry/21844
  • 问题是你需要在求幂的每一步取余数,而不仅仅是在最后。请参阅我链接的 SO 问题的第一个答案,了解您需要使用的算法,而不是 << 运算符。

标签: c++ modulus integer-overflow exponent


【解决方案1】:

试试这个代码。这个想法是为模加法、乘法和求幂引入新函数:

#define MOD 1000000007

inline int modadd(int a, int b) {
    return ((long long)a + b) % MOD;
}

inline int modmult(int a, int b) {
    return ((long long) a * b) % MOD;
}

inline unsigned modexp(unsigned base, unsigned exp)
{
  unsigned result = 1;
  while (exp > 0) {
      if (exp & 1) result = ((unsigned long long)result * base) % MOD;
      base = ((unsigned long long)base * base) % MOD;
      exp >>= 1;
  }
  return result;
}

int main(void)
{
    unsigned A[3] = {1, 2, 3};
    unsigned r[3];
    unsigned i, n = 3;

    r[0] = 0;
    r[1] = modmult(2, A[0]);
    for (i = 1; i < n; i++) {
        r[i+1] = modadd(r[i], modmult(A[i], modexp(2, i)));
    }
}

【讨论】:

  • 嘿,谢谢!我使用模幂函数解决了它!这也很棒。也许你能回答这个疑问?我似乎无法理解这一点。如果我正在计算 [x*(a^b)%mod+y%mod]%mod,如果我只使用 (a^b)%mod,将它与 x 相乘会给我正确的答案吗?逐步计算 (x*(a^b))%mod 不是更好的主意吗?只是想向自己证明为什么不包括 x 作品。
  • 如果a^b 的意思是“a 的 b 次方”,那么问题是即使a^b 没有溢出,x*(a^b) 也可能溢出整数范围。使用modmult(x, a^b) 或将x 转换为long long
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
相关资源
最近更新 更多