Problem p02679 (C++)

Buggy submission (status: Runtime Error):
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
using ll = long long int;
using int64 = long long int;

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

// ModInt begin

using ll = long long;
template <ll mod> struct ModInt {
  ll v;
  ll mod_pow(ll x, ll n) const {
    return (!n) ? 1 : (mod_pow((x * x) % mod, n / 2) * ((n & 1) ? x : 1)) % mod;
  }
  ModInt(ll a = 0) : v((a %= mod) < 0 ? a + mod : a) {}
  ModInt operator+(const ModInt &b) const {
    return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
  }
  ModInt operator-() const { return ModInt(-v); }
  ModInt operator-(const ModInt &b) const {
    return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
  }
  ModInt operator*(const ModInt &b) const { return (v * b.v) % mod; }
  ModInt operator/(const ModInt &b) const {
    return (v * mod_pow(b.v, mod - 2)) % mod;
  }

  bool operator==(const ModInt &b) const { return v == b.v; }
  bool operator!=(const ModInt &b) const { return !(*this == b); }
  ModInt &operator+=(const ModInt &b) {
    v += b.v;
    if (v >= mod)
      v -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &b) {
    v -= b.v;
    if (v < 0)
      v += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &b) {
    (v *= b.v) %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &b) {
    (v *= mod_pow(b.v, mod - 2)) %= mod;
    return *this;
  }
  ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
  // operator int() const { return int(v); }
  // operator long long int() const { return v; }
};

template <ll mod> ModInt<mod> pow(ModInt<mod> n, ll k) {
  return ModInt<mod>(n.mod_pow(n.v, k));
}

template <ll mod> ostream &operator<<(ostream &out, ModInt<mod> a) {
  return out << a.v;
}
template <ll mod> istream &operator>>(istream &in, ModInt<mod> &a) {
  in >> a.v;
  return in;
}

// ModInt end

using mint = ModInt<MOD>;

int main() {
  ll N;
  cin >> N;
  mint ans(0);

  ll a0 = 0, b0 = 0;
  map<pair<ll, ll>, int> posi, nega;
  for (int i = 0; i < N; i++) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 and b == 0) {
      ans += mint(1);
      continue;
    } else if (a == 0 or b == 0) {
      ll m = max(abs(a), abs(b));
      a /= m;
      b /= m;
    } else {
      ll g = __gcd(abs(a), abs(b));
      a /= g, b /= g;
    }

    // a は負ではない
    if (a < 0)
      a *= -1, b *= -1;

    if (a == 0)
      a0++;
    else if (b == 0)
      b0++;
    else if (b > 0)
      posi[make_pair(a, b)]++;
    else
      nega[make_pair(-b, a)]++;
  }

  // a0 から自然数個・b0 から自然数個・何も選ばない
  mint mul(0);
  mul += mint(2).pow(a0) - mint(1);
  mul += mint(2).pow(b0) - mint(1);
  mul += mint(1);
  for (auto e : posi) {
    ll a, b, n0;
    tie(a, b) = e.first;
    n0 = e.second;
    ll n1 = !nega.count(make_pair(a, b)) ? 0 : nega[make_pair(a, b)];

    // fprintf(stderr, "a = %lld, b = %lld, n0 = %lld, n1 = %lld\n", a, b, n0,
    // n1); n0 から自然数個・n1 から自然数個・何も選ばない
    mint add(0);
    add += mint(2).pow(n0) - mint(1);
    add += mint(2).pow(n1) - mint(1);
    add += mint(1);
    mul *= add;
  }
  for (auto e : nega) {
    ll a, b, n0;
    tie(a, b) = e.first;
    n0 = e.second;
    if (posi.count(make_pair(a, b)))
      continue;
    // fprintf(stderr, "a = %lld, b = %lld, n0 = %lld\n", a, b, n0);
    // n0 から任意個
    mul *= mint(2).pow(n0);
  }

  // 何も選んでいない場合以外
  ans += mul - mint(1);
  cout << ans << endl;
  return 1;
}


Fixed submission:
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
using ll = long long int;
using int64 = long long int;

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

// ModInt begin

using ll = long long;
template <ll mod> struct ModInt {
  ll v;
  ll mod_pow(ll x, ll n) const {
    return (!n) ? 1 : (mod_pow((x * x) % mod, n / 2) * ((n & 1) ? x : 1)) % mod;
  }
  ModInt(ll a = 0) : v((a %= mod) < 0 ? a + mod : a) {}
  ModInt operator+(const ModInt &b) const {
    return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
  }
  ModInt operator-() const { return ModInt(-v); }
  ModInt operator-(const ModInt &b) const {
    return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
  }
  ModInt operator*(const ModInt &b) const { return (v * b.v) % mod; }
  ModInt operator/(const ModInt &b) const {
    return (v * mod_pow(b.v, mod - 2)) % mod;
  }

  bool operator==(const ModInt &b) const { return v == b.v; }
  bool operator!=(const ModInt &b) const { return !(*this == b); }
  ModInt &operator+=(const ModInt &b) {
    v += b.v;
    if (v >= mod)
      v -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &b) {
    v -= b.v;
    if (v < 0)
      v += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &b) {
    (v *= b.v) %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &b) {
    (v *= mod_pow(b.v, mod - 2)) %= mod;
    return *this;
  }
  ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
  // operator int() const { return int(v); }
  // operator long long int() const { return v; }
};

template <ll mod> ModInt<mod> pow(ModInt<mod> n, ll k) {
  return ModInt<mod>(n.mod_pow(n.v, k));
}

template <ll mod> ostream &operator<<(ostream &out, ModInt<mod> a) {
  return out << a.v;
}
template <ll mod> istream &operator>>(istream &in, ModInt<mod> &a) {
  in >> a.v;
  return in;
}

// ModInt end

using mint = ModInt<MOD>;

int main() {
  ll N;
  cin >> N;
  mint ans(0);

  ll a0 = 0, b0 = 0;
  map<pair<ll, ll>, int> posi, nega;
  for (int i = 0; i < N; i++) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 and b == 0) {
      ans += mint(1);
      continue;
    } else if (a == 0 or b == 0) {
      ll m = max(abs(a), abs(b));
      a /= m;
      b /= m;
    } else {
      ll g = __gcd(abs(a), abs(b));
      a /= g, b /= g;
    }

    // a は負ではない
    if (a < 0)
      a *= -1, b *= -1;

    if (a == 0)
      a0++;
    else if (b == 0)
      b0++;
    else if (b > 0)
      posi[make_pair(a, b)]++;
    else
      nega[make_pair(-b, a)]++;
  }

  // a0 から自然数個・b0 から自然数個・何も選ばない
  mint mul(0);
  mul += mint(2).pow(a0) - mint(1);
  mul += mint(2).pow(b0) - mint(1);
  mul += mint(1);
  for (auto e : posi) {
    ll a, b, n0;
    tie(a, b) = e.first;
    n0 = e.second;
    ll n1 = !nega.count(make_pair(a, b)) ? 0 : nega[make_pair(a, b)];

    // fprintf(stderr, "a = %lld, b = %lld, n0 = %lld, n1 = %lld\n", a, b, n0,
    // n1); n0 から自然数個・n1 から自然数個・何も選ばない
    mint add(0);
    add += mint(2).pow(n0) - mint(1);
    add += mint(2).pow(n1) - mint(1);
    add += mint(1);
    mul *= add;
  }
  for (auto e : nega) {
    ll a, b, n0;
    tie(a, b) = e.first;
    n0 = e.second;
    if (posi.count(make_pair(a, b)))
      continue;
    // fprintf(stderr, "a = %lld, b = %lld, n0 = %lld\n", a, b, n0);
    // n0 から任意個
    mul *= mint(2).pow(n0);
  }

  // 何も選んでいない場合以外
  ans += mul - mint(1);
  cout << ans << endl;
  return 0;
}