Problem p02679 (C++) — buggy submission, verdict: Runtime Error

#include <iostream>
#include <map>
#include <utility>
#include <vector>

const int mod = 1000000007;
struct mint {
  long long x;
  mint(long long x = 0) : x((x % mod + mod) % mod) {}

  mint operator-() const { return mint(-x); }

  mint &operator+=(const mint &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint &a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint &a) {
    (x *= a.x) %= mod;
    return *this;
  }

  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }

  // べき乗
  mint pow(long long t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // 逆元を求める
  mint inv() const { return pow(mod - 2); }
  // 割り算　prime（素数）
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
// 入出力
std::istream &operator>>(std::istream &is, const mint &a) { return is >> a.x; }
std::ostream &operator<<(std::ostream &os, const mint &a) { return os << a.x; }

// 最大公約数を求める関数
long long gcd_(long long x, long long y) {
  // どちらかが0の場合
  if (x == 0)
    return y;
  if (y == 0)
    return x;
  // 　どのような値でも、0をかければ0になれる

  if (x < y) {
    long long tmp = x;
    x = y;
    y = tmp;
  }
  long long r = x % y;
  while (r != 0) {
    x = y;
    y = r;
    r = x % y;
  }
  return y;
}

int main() {
  int n;
  std::cin >> n;
  int zero = 0;
  std::map<std::pair<long long, long long>, std::pair<int, int>> mp;

  for (int i = 0; i < n; i++) {
    long long a, b;
    std::cin >> a >> b;
    // 例外処理
    if (a == 0 && b == 0) {
      zero++;
      continue;
    }
    // a, bを標準化する
    long long g = gcd_(a, b);
    a /= g;
    b /= g;

    // 180度回転
    if (b < 0) {
      a = -a;
      b = -b;
    } else if (b == 0 && a < 0) {
      a = -a;
    }

    // 90度回転
    bool rot = false;
    if (a <= 0) {
      rot = true;
      long long tmp = -a;
      a = b;
      b = tmp;
    }

    // mapへ格納
    if (rot) { // 90度回転したものは、secondグループ
      mp[{a, b}].second++;
    } else { // firstグループ
      mp[{a, b}].first++;
    }
  }

  mint ans = 1;
  for (auto p : mp) {
    int s = p.second.first;
    int t = p.second.second;
    mint now = 1; // どちらのグループからも選ばないとき
    now += mint(2).pow(s) - 1; // sからの選び方（1匹以上）
    now += mint(2).pow(t) - 1; // tからの選び方（1匹以上）
    ans *= now;
  }
  ans -= 1;
  ans += zero;
  std::cout << ans << std::endl;

  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <map>
#include <utility>
#include <vector>

const int mod = 1000000007;
struct mint {
  long long x;
  mint(long long x = 0) : x((x % mod + mod) % mod) {}

  mint operator-() const { return mint(-x); }

  mint &operator+=(const mint &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint &a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint &a) {
    (x *= a.x) %= mod;
    return *this;
  }

  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }

  // べき乗
  mint pow(long long t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // 逆元を求める
  mint inv() const { return pow(mod - 2); }
  // 割り算　prime（素数）
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
// 入出力
std::istream &operator>>(std::istream &is, const mint &a) { return is >> a.x; }
std::ostream &operator<<(std::ostream &os, const mint &a) { return os << a.x; }

// 最大公約数を求める関数
long long gcd_(long long x, long long y) {
  if (x % y == 0)
    return y;
  return gcd_(y, x % y);
}

int main() {
  int n;
  std::cin >> n;
  int zero = 0;
  std::map<std::pair<long long, long long>, std::pair<int, int>> mp;

  for (int i = 0; i < n; i++) {
    long long a, b;
    std::cin >> a >> b;
    // 例外処理
    if (a == 0 && b == 0) {
      zero++;
      continue;
    }
    // a, bを標準化する
    long long g = gcd_(a, b);
    a /= g;
    b /= g;

    // 180度回転
    if (b < 0) {
      a = -a;
      b = -b;
    } else if (b == 0 && a < 0) {
      a = -a;
    }

    // 90度回転
    bool rot = false;
    if (a <= 0) {
      rot = true;
      long long tmp = -a;
      a = b;
      b = tmp;
    }

    // mapへ格納
    if (rot) { // 90度回転したものは、secondグループ
      mp[{a, b}].second++;
    } else { // firstグループ
      mp[{a, b}].first++;
    }
  }

  mint ans = 1;
  for (auto p : mp) {
    int s = p.second.first;
    int t = p.second.second;
    mint now = 1; // どちらのグループからも選ばないとき
    now += mint(2).pow(s) - 1; // sからの選び方（1匹以上）
    now += mint(2).pow(t) - 1; // tからの選び方（1匹以上）
    ans *= now;
  }
  ans -= 1;
  ans += zero;
  std::cout << ans << std::endl;

  return 0;
}