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

#include <bits/stdc++.h>
using namespace std;

#define watch(x) cerr << (#x) << ": " << (x) << endl

typedef long long LL;

const int N = 200009, MOD = 1000000007;

struct mint {
  int val;

  mint(int v = 0) {
    val = v % MOD;
    if (val < 0)
      val += MOD;
  }

  static int mod_inv(int a, int m = MOD) {
    int g = m, r = a, x = 0, y = 1;

    while (r != 0) {
      int q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    return x < 0 ? x + m : x;
  }

  explicit operator int() const { return val; }

  mint &operator+=(const mint &other) {
    val += other.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }

  mint &operator-=(const mint &other) {
    val -= other.val;
    if (val < 0)
      val += MOD;
    return *this;
  }

  mint &operator*=(const mint &other) {
    val = ((uint64_t)val * other.val) % MOD;
    return *this;
  }

  mint &operator/=(const mint &other) { return *this *= other.inv(); }

  friend mint operator+(const mint &a, const mint &b) { return mint(a) += b; }
  friend mint operator-(const mint &a, const mint &b) { return mint(a) -= b; }
  friend mint operator*(const mint &a, const mint &b) { return mint(a) *= b; }
  friend mint operator/(const mint &a, const mint &b) { return mint(a) /= b; }

  mint &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }

  mint &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }

  mint operator++(int32_t) {
    mint before = *this;
    ++*this;
    return before;
  }
  mint operator--(int32_t) {
    mint before = *this;
    --*this;
    return before;
  }

  mint operator-() const { return val == 0 ? 0 : MOD - val; }

  bool operator==(const mint &other) const { return val == other.val; }
  bool operator!=(const mint &other) const { return val != other.val; }

  mint inv() const { return mod_inv(val); }

  mint pow(int p) const {
    mint a = *this, result = 1;

    while (p > 0) {
      if (p & 1)
        result *= a;

      a *= a;
      p >>= 1;
    }

    return result;
  }

  friend ostream &operator<<(ostream &stream, const mint &m) {
    return stream << m.val;
  }
};

LL n, a[N], b[N];
mint TWO = 2;

pair<LL, LL> get_p(LL ca, LL ba) {
  if (ba < 0) {
    ca = -ca, ba = -ba;
  }
  if (ca == 0 && ba != 0) {
    ba = 1;
  } else if (ba == 0 && ca != 0) {
    ca = 1;
  } else if (ba != 0 && ca != 0) {
    LL g = __gcd(ca, ba);
    ca /= g;
    ba /= g;
  }
  return {ca, ba};
}

int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i];
  }

  map<pair<LL, LL>, int> f;
  for (int i = 0; i < n; ++i) {
    pair<LL, LL> abi = get_p(a[i], b[i]);
    f[abi]++;
  }

  mint ans = 1;
  set<pair<LL, LL>> seen;
  pair<LL, LL> zeropair;
  seen.insert(zeropair);
  for (auto p : f) {
    pair<LL, LL> cur = p.first;
    if (seen.count(cur))
      continue;
    int ct1 = p.second;
    pair<LL, LL> opp = get_p(-cur.second, cur.first);
    int ct2 = f[opp];

    mint mult = TWO.pow(ct1) + TWO.pow(ct2) - 1;
    ans *= mult;
    seen.insert(cur);
    seen.insert(opp);
  }

  ans += f[zeropair];

  cout << ans - 1 << '\\n';

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define watch(x) cerr << (#x) << ": " << (x) << endl

typedef long long LL;

const int N = 200009, MOD = 1000000007;

struct mint {
  int val;

  mint(int v = 0) {
    val = v % MOD;
    if (val < 0)
      val += MOD;
  }

  static int mod_inv(int a, int m = MOD) {
    int g = m, r = a, x = 0, y = 1;

    while (r != 0) {
      int q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    return x < 0 ? x + m : x;
  }

  explicit operator int() const { return val; }

  mint &operator+=(const mint &other) {
    val += other.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }

  mint &operator-=(const mint &other) {
    val -= other.val;
    if (val < 0)
      val += MOD;
    return *this;
  }

  mint &operator*=(const mint &other) {
    val = ((uint64_t)val * other.val) % MOD;
    return *this;
  }

  mint &operator/=(const mint &other) { return *this *= other.inv(); }

  friend mint operator+(const mint &a, const mint &b) { return mint(a) += b; }
  friend mint operator-(const mint &a, const mint &b) { return mint(a) -= b; }
  friend mint operator*(const mint &a, const mint &b) { return mint(a) *= b; }
  friend mint operator/(const mint &a, const mint &b) { return mint(a) /= b; }

  mint &operator++() {
    val = val == MOD - 1 ? 0 : val + 1;
    return *this;
  }

  mint &operator--() {
    val = val == 0 ? MOD - 1 : val - 1;
    return *this;
  }

  mint operator++(int32_t) {
    mint before = *this;
    ++*this;
    return before;
  }
  mint operator--(int32_t) {
    mint before = *this;
    --*this;
    return before;
  }

  mint operator-() const { return val == 0 ? 0 : MOD - val; }

  bool operator==(const mint &other) const { return val == other.val; }
  bool operator!=(const mint &other) const { return val != other.val; }

  mint inv() const { return mod_inv(val); }

  mint pow(int p) const {
    mint a = *this, result = 1;

    while (p > 0) {
      if (p & 1)
        result *= a;

      a *= a;
      p >>= 1;
    }

    return result;
  }

  friend ostream &operator<<(ostream &stream, const mint &m) {
    return stream << m.val;
  }
};

struct frac {
  bool neg;
  int num, den;
  frac(int _n, int _d) {
    if ((_n < 0 && _d > 0) || (_n > 0 && _d < 0)) {
      neg = true;
    } else {
      neg = false;
    }
    if (_n == 0)
      neg = false;
    _n = abs(_n);
    _d = abs(_d);
    int g = __gcd(_n, _d);
    num = _n / g, den = _d / g;
  }

  bool operator<(const frac &other) const {
    if (neg != other.neg)
      return neg < other.neg;
    if (num != other.num)
      return num < other.num;
    return den < other.den;
  }

  frac opp() const {
    int nn = den, dd = num;
    if (!neg)
      nn *= -1;
    frac fo(nn, dd);
    return fo;
  }
};

int n, a[N], b[N];

int main() {

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i];
  }

  map<frac, int> f;

  for (int i = 0; i < n; ++i) {
    frac fr(a[i], b[i]);
    f[fr]++;
  }

  set<frac> seen;
  mint ans = 1, two = 2;
  for (auto p : f) {
    if (seen.count(p.first))
      continue;

    frac op = p.first.opp();
    int ta = p.second, tb = f[op];

    ans *= two.pow(ta) + two.pow(tb) - 1;
    seen.insert(p.first);
    seen.insert(op);
  }

  cout << ans - 1 << '\\n';

  return 0;
}