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

#include <bits/stdc++.h>
typedef long long int ll;
#define rep(i, n) for (ll i = 0; i < (n); i++)

using namespace std;
// {{{ Modint
// using mint = modint<1000000007>;
// mint x = 2;
// std::cout << x.a << std::endl;
template <std::int64_t M> class modint {
public:
  int64_t a;

  explicit constexpr modint(const int64_t x = 0) noexcept
      : a((x % M + M) % M) {}
  constexpr int64_t &value() noexcept { return a; }
  constexpr const int64_t &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= M) {
      a -= M;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += M;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % M;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    int64_t exp = M - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
  constexpr modint pow(ll t) const {
    if (!t)
      return modint(1);
    modint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
};
// }}}
using mint = modint<1000000007>;

typedef pair<ll, ll> v2d;

ll N;
map<v2d, ll> mp; // x >= 0
map<v2d, bool> used;

ll gcd(ll x, ll y) {
  if (y < x)
    swap(x, y);
  // cout << x << " " << y << endl;
  if (x == 0 && y == 0)
    return 1;
  if (x == 0)
    return y;
  if (y % x == 0)
    return x;
  return gcd(y % x, x);
}

ll absl(ll x) {
  if (x < 0)
    return -x;
  return x;
}

// 2^x
mint pow2(ll x) {
  if (x == 0)
    return mint(1);

  if (x % 2 == 0) {
    auto t = pow2(x / 2);
    return t * t;
  }

  auto t = pow2(x / 2);
  return t * t * mint(2);
}

int main() {
  cin >> N;
  rep(i, N) {
    ll x, y;
    cin >> x >> y;
    ll g = gcd(absl(x), absl(y));
    x /= g;
    y /= g;
    if (x < 0) {
      x *= -1;
      y *= -1;
    }
    if (x == 0 && y < 0) {
      y *= -1;
    }
    // cout << x << " " << y << " " << g << endl;
    mp[v2d(x, y)]++;
  }
  // (0, 0) を含む場合
  mint ans(mp[v2d(0, 0)]);
  used[v2d(0, 0)] = true;

  // (0, 0) を含まない場合
  mint t(1);
  for (auto e : mp) {
    auto v1 = e.first;
    auto n1 = e.second;
    auto v2 = v2d(v1.second, -1 * v1.first);
    if (used[v1]) {
      continue;
    }
    if (v2.first < 0) {
      v2.first *= -1;
      v2.second *= -1;
    }
    if (v2.first == 0 && v2.second < 0) {
      v2.second *= -1;
    }
    auto n2 = mp[v2];
    if (n2 == 0) {
      t *= pow2(n1);
    } else {
      t *= pow2(n1) + pow2(n2) - mint(1);
    }
    used[v1] = true;
    used[v2] = true;
  }

  // 空はだめ
  ans += t - mint(1);

  cout << ans.value() << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
typedef long long int ll;
#define rep(i, n) for (ll i = 0; i < (n); i++)

using namespace std;
// {{{ Modint
// using mint = modint<1000000007>;
// mint x = 2;
// std::cout << x.a << std::endl;
template <std::int64_t M> class modint {
public:
  int64_t a;

  explicit constexpr modint(const int64_t x = 0) noexcept
      : a((x % M + M) % M) {}
  constexpr int64_t &value() noexcept { return a; }
  constexpr const int64_t &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= M) {
      a -= M;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += M;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % M;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    int64_t exp = M - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
  constexpr modint pow(ll t) const {
    if (!t)
      return modint(1);
    modint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
};
// }}}
using mint = modint<1000000007>;

typedef pair<ll, ll> v2d;

ll N;
map<v2d, ll> mp; // x >= 0
map<v2d, bool> used;

ll gcd(ll x, ll y) {
  if (y < x)
    swap(x, y);
  // cout << x << " " << y << endl;
  if (y % x == 0)
    return x;
  return gcd(y % x, x);
}

ll absl(ll x) {
  if (x < 0)
    return -x;
  return x;
}

// 2^x
mint pow2(ll x) {
  if (x == 0)
    return mint(1);

  if (x % 2 == 0) {
    auto t = pow2(x / 2);
    return t * t;
  }

  auto t = pow2(x / 2);
  return t * t * mint(2);
}

int main() {
  cin >> N;
  rep(i, N) {
    ll x, y;
    cin >> x >> y;
    ll g = gcd(absl(x), absl(y));
    x /= g;
    y /= g;
    if (x < 0) {
      x *= -1;
      y *= -1;
    }
    // cout << x << " " << y << " " << g << endl;
    mp[v2d(x, y)]++;
  }
  // (0, 0) を含む場合
  mint ans(mp[v2d(0, 0)]);

  // (0, 0) を含まない場合
  mint t(1);
  for (auto e : mp) {
    auto v1 = e.first;
    auto n1 = e.second;
    auto v2 = v2d(v1.second, -1 * v1.first);
    if (used[v1]) {
      continue;
    }
    if (v2.first < 0) {
      v2.first *= -1;
      v2.second *= -1;
    }
    auto n2 = mp[v2];
    if (n2 == 0) {
      t *= pow2(n1);
    } else {
      t *= pow2(n1) + pow2(n2) - mint(1);
    }
    used[v1] = true;
    used[v2] = true;
  }

  // 空はだめ
  ans += t - mint(1);

  cout << ans.value() << endl;
  return 0;
}