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

// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using ll = long signed long;
using ull = long unsigned long;
using ld = long double;
using namespace std;

// AtCoder/Codeforces 用 デバッグ検知
#ifdef ONLINE_JUDGE
constexpr bool DEBUG_MODE = false;
#else
constexpr bool DEBUG_MODE = true;
#endif

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i, n) for (long long i = 0, i##_len = (n); i < i##_len; i++)
#define RANGE(i, is, ie)                                                       \\
  for (long long i = (is), i##_end = (ie); i <= i##_end; i++)
#define DSRNG(i, is, ie)                                                       \\
  for (long long i = (is), i##_end = (ie); i >= i##_end; i--)
#define STEP(i, is, ie, step)                                                  \\
  for (long long i = (is), i##_end = (ie), i##_step = (step); i <= i##_end;    \\
       i += i##_step)
#define UNIQUE(v)                                                              \\
  do {                                                                         \\
    sort((v).begin(), (v).end());                                              \\
    (v).erase(unique((v).begin(), (v).end()), (v).end());                      \\
  } while (false)
#define FOREACH(i, q) for (auto &i : q)
template <class T> bool chmax(T &a, const T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q, t, f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) {
  if (is_integral<T>() || is_floating_point<T>())
    cerr << "\\e[32m" << x << "\\e[m";
  else
    cerr << x;
}
template <> void DUMP_PROC<char>(char x) {
  cerr << "\\e[36m\\'" << x << "\\'\\e[m";
}
template <> void DUMP_PROC<string>(string x) {
  cerr << "\\e[33m\\"" << x << "\\"\\e[m";
}
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) {
  cerr << "{";
  DUMP_PROC(x.first);
  cerr << ", ";
  DUMP_PROC(x.second);
  cerr << "}";
}
template <typename... T, typename U, U... Seq>
void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) {
  (void)(int[]){(cerr << ((const char *[]){"", ", "})[!!Seq]
                      << (DUMP_PROC(get<Seq>(x)), ""),
                 0)...};
}
template <typename... T> void DUMP_PROC(tuple<T...> x) {
  cerr << "{";
  DUMP_PROC(x, index_sequence_for<T...>());
  cerr << "}";
}
template <typename T> void DUMP_PROC(vector<T> x) {
  cerr << "[";
  for (auto &xi : x) {
    DUMP_PROC(xi);
    cerr << (&xi != &*x.rbegin() ? ", " : "");
  }
  cerr << "]";
}
template <typename T>
void DUMP_FUNC(T x, const char *name, const char *fn, int ln) {
  cerr << "\\e[32m[DEBUG]\\e[m " << name << ": ";
  DUMP_PROC(x);
  cerr << " @ " << fn << "(" << ln << ")" << endl;
}

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
  size_t sz;
  qin(size_t _sz = 1) : sz(_sz) {}
  template <typename T> operator T() const {
    T a;
    cin >> a;
    return a;
  }
  template <typename T> operator vector<T>() const {
    vector<T> a(sz);
    for (size_t i = 0; i < sz; i++)
      cin >> a[i];
    return a;
  }
  template <typename T, typename U> operator pair<T, U>() const {
    T f;
    U s;
    cin >> f >> s;
    return pair<T, U>(f, s);
  }
};
qin in1; // input one
template <typename T> void say(const T x, const char *end = "\\n") {
  cout << x << end;
}
void say(const ld x, const char *end = "\\n") {
  cout << setprecision(30) << x << end;
}
template <typename T>
void say(const vector<T> x, const char *sep = " ", const char *end = "\\n") {
  REP(i, x.size()) { cout << x[i] << (i + 1 == i_len ? end : sep); }
}
template <typename T>
void say(const vector<vector<T>> x, const char *sep = " ",
         const char *end = "\\n") {
  REP(i, x.size()) { say(x[i], sep, end); }
}

// モジュール
// [[LIBRARY]]

// い　つ　も　の
constexpr long long pdiv = 1000000007LL;
// constexpr long long pdiv = 998244353LL;
struct modint {
  using ll = long long;
  ll x = 0;
  modint(ll _x = 0) : x(_x) { compile(); }
  void compile() { x = (x % pdiv + pdiv) % pdiv; }
  modint pow(long long n) const {
    ((n %= pdiv - 1) += pdiv - 1) %= pdiv - 1;
    long long result = 1;
    long long base = x;
    long long mask = 1;
    while (mask <= n) {
      if (n & mask)
        (result *= base) %= pdiv;
      mask <<= 1;
      (base *= base) %= pdiv;
    }
    return modint(result);
  }
  modint inv() const { return this->pow(pdiv - 2); }
  modint operator+(long long a) const { return modint(x + a); }
  modint operator-(long long a) const { return modint(pdiv + x - a); }
  modint operator*(long long a) const { return modint(x * a); }
  modint operator/(long long a) const { return modint(x * modint(a).inv().x); }
  modint operator+(modint a) const { return modint(x + a.x); }
  modint operator-(modint a) const { return modint(pdiv + x - a.x); }
  modint operator*(modint a) const { return modint(x * a.x); }
  modint operator/(modint a) const { return modint(x * a.pow(pdiv - 2).x); }
  template <typename T> modint &operator+=(T a) { return *this = *this + a; }
  template <typename T> modint &operator-=(T a) { return *this = *this - a; }
  template <typename T> modint &operator*=(T a) { return *this = *this * a; }
  template <typename T> modint &operator/=(T a) { return *this = *this / a; }
  modint operator-() const { return modint(pdiv - x); }
  template <typename T> modint &operator=(T a) {
    x = a;
    compile();
    return *this;
  }
};
modint operator+(const long long a, const modint b) { return modint(a) + b; }
modint operator-(const long long a, const modint b) { return modint(a) - b; }
modint operator*(const long long a, const modint b) { return modint(a) * b; }
modint operator/(const long long a, const modint b) { return modint(a) / b; }
modint operator"" _p(unsigned long long _x) { return modint(_x); }
ostream &operator<<(ostream &ost, const modint a) {
  ost << a.x;
  return ost;
}
istream &operator>>(istream &ist, modint &a) {
  ist >> a.x;
  return ist;
}
modint pow(modint a, long long n) { return a.pow(n); }
vector<modint> fac_cache = {1}, invfac_cache = {1};
void prepare_fac(long long nmax) {
  long long m0 = fac_cache.size() - 1;
  if (m0 < nmax) {
    fac_cache.resize(nmax + 1);
    invfac_cache.resize(nmax + 1);
  }
  for (long long n = m0 + 1; n <= nmax; n++) {
    fac_cache[n] = fac_cache[n - 1] * n;
    invfac_cache[n] = fac_cache[n].inv();
  }
}
modint fac(long long n) {
  prepare_fac(n);
  return fac_cache[n];
}
modint invfac(long long n) {
  prepare_fac(n);
  return invfac_cache[n];
}
bool isinpascal(long long n, long long r) { return n >= 0 && r >= 0 && n >= r; }
modint nCr(long long n, long long r) {
  return !isinpascal(n, r) ? 0_p : fac(n) * invfac(r) * invfac(n - r);
}
modint nPr(long long n, long long r) {
  return !isinpascal(n, r) ? 0_p : fac(n) * invfac(n - r);
}
modint nHr(long long n, long long r) { return nCr(n + r - 1, r); }

pair<ll, ll> make_hash(ll a, ll b) {
  if (!a && !b) {
    return {0, 0};
  } else if (!b) {
    return {1, 0};
  } else if (!a) {
    return {0, 1};
  } else {
    if (a < 0) {
      a *= -1;
      b *= -1;
    }
    ll g = gcd(a, b);
    a /= g;
    b /= g;
    return {a, b};
  }
}

pair<ll, ll> counter_hash(pair<ll, ll> x) {
  ll a, b;
  tie(a, b) = x;
  if (!a && !b) {
    return {0, 0};
  } else if (!b) {
    return {0, 1};
  } else if (!a) {
    return {1, 0};
  } else {
    swap(a, b);
    if (a < 0) {
      a *= -1;
    } else {
      b *= -1;
    }
    return {a, b};
  }
}

// 処理内容
int main() {

  ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
  cin.tie(nullptr); // インタラクティブ問題ではコメントアウトすること

  ll n = in1;
  vector<pair<ll, ll>> ab;
  REP(i, n) {
    ll a, b;
    cin >> a >> b;
    ab.emplace_back(a, b);
  }

  map<pair<ll, ll>, ll> h;
  ll nh = 0, nz = 0, ni = 0;
  REP(i, n) {
    ll a, b;
    tie(a, b) = ab[i];
    h[make_hash(a, b)]++;
  }
  vector<pair<ll, ll>> tak;
  set<pair<ll, ll>> vst;
  for (const auto &p : h) {
    pair<ll, ll> key;
    ll num;
    tie(key, num) = p;
    if (key == make_pair(0LL, 0LL)) {
      nh = num;
      continue;
    }
    if (vst.find(key) != vst.end())
      continue;
    auto hky = counter_hash(key);
    tak.emplace_back(num, h[hky]);
    vst.insert(hky);
  }

  // DUMP(tak);

  modint ans = 1;
  for (const auto &p : tak) {
    ll u, v;
    tie(u, v) = p;
    ans *= (2_p).pow(u) + (2_p).pow(v) - 1;
  }
  say(ans + nh - 1);
}


Error: 0

Fixed submission:

// May this submission get accepted
#include <bits/stdc++.h>

// エイリアス
using ll = long signed long;
using ull = long unsigned long;
using ld = long double;
using namespace std;

// AtCoder/Codeforces 用 デバッグ検知
#ifdef ONLINE_JUDGE
constexpr bool DEBUG_MODE = false;
#else
constexpr bool DEBUG_MODE = true;
#endif

// エイリアス (補完・コンパイルが重くなる)
// #include <boost/multiprecision/cpp_int.hpp>
// using mll = boost::multiprecision::cpp_int;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i, n) for (long long i = 0, i##_len = (n); i < i##_len; i++)
#define RANGE(i, is, ie)                                                       \\
  for (long long i = (is), i##_end = (ie); i <= i##_end; i++)
#define DSRNG(i, is, ie)                                                       \\
  for (long long i = (is), i##_end = (ie); i >= i##_end; i--)
#define STEP(i, is, ie, step)                                                  \\
  for (long long i = (is), i##_end = (ie), i##_step = (step); i <= i##_end;    \\
       i += i##_step)
#define UNIQUE(v)                                                              \\
  do {                                                                         \\
    sort((v).begin(), (v).end());                                              \\
    (v).erase(unique((v).begin(), (v).end()), (v).end());                      \\
  } while (false)
#define FOREACH(i, q) for (auto &i : q)
template <class T> bool chmax(T &a, const T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
constexpr int INF = numeric_limits<int>::max();
constexpr long long LINF = numeric_limits<long long>::max();
constexpr long double EPS = 1e-10L;
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define IIF(q, t, f) ((q) ? (t) : (f))
#define DUMP(q) DUMP_FUNC(q, #q, __FILE__, __LINE__)
template <typename T> void DUMP_PROC(T x) {
  if (is_integral<T>() || is_floating_point<T>())
    cerr << "\\e[32m" << x << "\\e[m";
  else
    cerr << x;
}
template <> void DUMP_PROC<char>(char x) {
  cerr << "\\e[36m\\'" << x << "\\'\\e[m";
}
template <> void DUMP_PROC<string>(string x) {
  cerr << "\\e[33m\\"" << x << "\\"\\e[m";
}
template <typename T, typename U> void DUMP_PROC(pair<T, U> x) {
  cerr << "{";
  DUMP_PROC(x.first);
  cerr << ", ";
  DUMP_PROC(x.second);
  cerr << "}";
}
template <typename... T, typename U, U... Seq>
void DUMP_PROC(tuple<T...> &x, integer_sequence<U, Seq...>) {
  (void)(int[]){(cerr << ((const char *[]){"", ", "})[!!Seq]
                      << (DUMP_PROC(get<Seq>(x)), ""),
                 0)...};
}
template <typename... T> void DUMP_PROC(tuple<T...> x) {
  cerr << "{";
  DUMP_PROC(x, index_sequence_for<T...>());
  cerr << "}";
}
template <typename T> void DUMP_PROC(vector<T> x) {
  cerr << "[";
  for (auto &xi : x) {
    DUMP_PROC(xi);
    cerr << (&xi != &*x.rbegin() ? ", " : "");
  }
  cerr << "]";
}
template <typename T>
void DUMP_FUNC(T x, const char *name, const char *fn, int ln) {
  cerr << "\\e[32m[DEBUG]\\e[m " << name << ": ";
  DUMP_PROC(x);
  cerr << " @ " << fn << "(" << ln << ")" << endl;
}

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// 標準入出力
struct qin { // query input
  size_t sz;
  qin(size_t _sz = 1) : sz(_sz) {}
  template <typename T> operator T() const {
    T a;
    cin >> a;
    return a;
  }
  template <typename T> operator vector<T>() const {
    vector<T> a(sz);
    for (size_t i = 0; i < sz; i++)
      cin >> a[i];
    return a;
  }
  template <typename T, typename U> operator pair<T, U>() const {
    T f;
    U s;
    cin >> f >> s;
    return pair<T, U>(f, s);
  }
};
qin in1; // input one
template <typename T> void say(const T x, const char *end = "\\n") {
  cout << x << end;
}
void say(const ld x, const char *end = "\\n") {
  cout << setprecision(30) << x << end;
}
template <typename T>
void say(const vector<T> x, const char *sep = " ", const char *end = "\\n") {
  REP(i, x.size()) { cout << x[i] << (i + 1 == i_len ? end : sep); }
}
template <typename T>
void say(const vector<vector<T>> x, const char *sep = " ",
         const char *end = "\\n") {
  REP(i, x.size()) { say(x[i], sep, end); }
}

// モジュール
// [[LIBRARY]]

// い　つ　も　の
constexpr long long pdiv = 1000000007LL;
// constexpr long long pdiv = 998244353LL;
struct modint {
  using ll = long long;
  ll x = 0;
  modint(ll _x = 0) : x(_x) { compile(); }
  void compile() { x = (x % pdiv + pdiv) % pdiv; }
  modint pow(long long n) const {
    ((n %= pdiv - 1) += pdiv - 1) %= pdiv - 1;
    long long result = 1;
    long long base = x;
    long long mask = 1;
    while (mask <= n) {
      if (n & mask)
        (result *= base) %= pdiv;
      mask <<= 1;
      (base *= base) %= pdiv;
    }
    return modint(result);
  }
  modint inv() const { return this->pow(pdiv - 2); }
  modint operator+(long long a) const { return modint(x + a); }
  modint operator-(long long a) const { return modint(pdiv + x - a); }
  modint operator*(long long a) const { return modint(x * a); }
  modint operator/(long long a) const { return modint(x * modint(a).inv().x); }
  modint operator+(modint a) const { return modint(x + a.x); }
  modint operator-(modint a) const { return modint(pdiv + x - a.x); }
  modint operator*(modint a) const { return modint(x * a.x); }
  modint operator/(modint a) const { return modint(x * a.pow(pdiv - 2).x); }
  template <typename T> modint &operator+=(T a) { return *this = *this + a; }
  template <typename T> modint &operator-=(T a) { return *this = *this - a; }
  template <typename T> modint &operator*=(T a) { return *this = *this * a; }
  template <typename T> modint &operator/=(T a) { return *this = *this / a; }
  modint operator-() const { return modint(pdiv - x); }
  template <typename T> modint &operator=(T a) {
    x = a;
    compile();
    return *this;
  }
};
modint operator+(const long long a, const modint b) { return modint(a) + b; }
modint operator-(const long long a, const modint b) { return modint(a) - b; }
modint operator*(const long long a, const modint b) { return modint(a) * b; }
modint operator/(const long long a, const modint b) { return modint(a) / b; }
modint operator"" _p(unsigned long long _x) { return modint(_x); }
ostream &operator<<(ostream &ost, const modint a) {
  ost << a.x;
  return ost;
}
istream &operator>>(istream &ist, modint &a) {
  ist >> a.x;
  return ist;
}
modint pow(modint a, long long n) { return a.pow(n); }
vector<modint> fac_cache = {1}, invfac_cache = {1};
void prepare_fac(long long nmax) {
  long long m0 = fac_cache.size() - 1;
  if (m0 < nmax) {
    fac_cache.resize(nmax + 1);
    invfac_cache.resize(nmax + 1);
  }
  for (long long n = m0 + 1; n <= nmax; n++) {
    fac_cache[n] = fac_cache[n - 1] * n;
    invfac_cache[n] = fac_cache[n].inv();
  }
}
modint fac(long long n) {
  prepare_fac(n);
  return fac_cache[n];
}
modint invfac(long long n) {
  prepare_fac(n);
  return invfac_cache[n];
}
bool isinpascal(long long n, long long r) { return n >= 0 && r >= 0 && n >= r; }
modint nCr(long long n, long long r) {
  return !isinpascal(n, r) ? 0_p : fac(n) * invfac(r) * invfac(n - r);
}
modint nPr(long long n, long long r) {
  return !isinpascal(n, r) ? 0_p : fac(n) * invfac(n - r);
}
modint nHr(long long n, long long r) { return nCr(n + r - 1, r); }

ll counter_hash(ll x) {
  if (x == 0) {
    return pdiv;
  } else if (x == pdiv) {
    return 0;
  } else {
    return modint(-x).inv().x;
  }
}

// 処理内容
int main() {

  ios::sync_with_stdio(false); // stdioを使うときはコメントアウトすること
  cin.tie(nullptr); // インタラクティブ問題ではコメントアウトすること

  ll n = in1;
  vector<pair<ll, ll>> ab;
  REP(i, n) {
    ll a, b;
    cin >> a >> b;
    ab.emplace_back(a, b);
  }

  map<ll, ll> h;
  ll nh = 0;
  REP(i, n) {
    ll a, b;
    tie(a, b) = ab[i];
    ll hx;
    if (!a && !b) {
      nh++;
      continue;
    } else if (!b) {
      hx = pdiv;
    } else if (!a) {
      hx = 0;
    } else {
      if ((a != 0 && a % pdiv == 0) || (b != 0 && b % pdiv == 0))
        exit(1);
      hx = (modint(a) / modint(b)).x;
    }
    h[hx]++;
  }
  vector<pair<ll, ll>> tak;
  set<ll> vst;
  for (const auto &p : h) {
    ll key, num;
    tie(key, num) = p;
    if (vst.find(key) != vst.end())
      continue;
    ll hky = counter_hash(key);
    tak.emplace_back(num, h[hky]);
    vst.insert(hky);
  }

  modint ans = 1;
  for (const auto &p : tak) {
    ll u, v;
    tie(u, v) = p;
    ans *= (2_p).pow(u) + (2_p).pow(v) - 1;
  }
  say(ans + nh - 1);
}