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

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;

template <class T> inline bool chmax(T &a, const T &b) {
  if (b > a) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

constexpr int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr double PI = M_PI;

template <int mod> class ModInt {
private:
  long long val;

public:
  ModInt(const long long v = 0) : val(v % mod) {
    if (val < 0)
      val += mod;
  }
  ModInt(const ModInt &v) : val(v.val) {}
  ModInt &operator=(const long long v) {
    val = v;
    return *this;
  }
  ModInt &operator=(const ModInt &v) {
    if (this != &v)
      val = v.val;
    return *this;
  }
  ModInt operator+() const { return ModInt(val); }
  ModInt operator-() const { return ModInt(-val); }
  ModInt operator+(const ModInt &v) const { return ModInt(*this) += v; }
  ModInt operator-(const ModInt &v) const { return ModInt(*this) -= v; }
  ModInt operator*(const ModInt &v) const { return ModInt(*this) *= v; }
  ModInt operator/(const ModInt &v) const { return ModInt(*this) /= v; }
  ModInt &operator+=(const ModInt &v) {
    val += v.val;
    if (val >= mod)
      val -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &v) {
    val -= v.val;
    if (val < 0)
      val += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &v) {
    val *= v.val;
    if (val >= mod)
      val %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &v) {
    val *= v.inverse();
    if (val >= mod)
      val %= mod;
    return *this;
  }
  ModInt &operator++() {
    ++val;
    if (val >= mod)
      val -= mod;
    return *this;
  }
  ModInt &operator--() {
    --val;
    if (val < 0)
      val += mod;
    return *this;
  }
  ModInt operator++(int) {
    ModInt tmp(*this);
    operator++();
    return tmp;
  }
  ModInt operator--(int) {
    ModInt tmp(*this);
    operator--();
    return tmp;
  }
  bool operator==(const ModInt &v) const { return val == v.val; }
  bool operator!=(const ModInt &v) const { return !(*this == v); }
  friend istream &operator>>(istream &s, ModInt &v) {
    long long tmp;
    s >> tmp;
    v = ModInt(tmp);
    return s;
  }
  friend ostream &operator<<(ostream &s, const ModInt &v) { return s << v.val; }
  ModInt inverse() const {
    long long n = val, res = 1;
    while (n > 1) {
      res *= (mod - mod / n);
      res %= mod;
      n = mod % n;
    }
    return ModInt(res);
  }
  friend ModInt modpow(ModInt v, long long n) {
    ModInt res(1);
    for (; n > 0; n >>= 1) {
      if (n & 1)
        res *= v;
      v *= v;
    }
    return res;
  }
};

long long gcd(long long a, long long b) {
  if (a < b)
    std::swap(a, b);
  if (b == 0)
    return a;

  while (b > 0) {
    long long buf = b;
    b = a % b;
    a = buf;
  }
  return a;
}

void solve() {
  ll n;
  cin >> n;
  vector<pair<ll, ll>> ab(n);
  for (int i = 0; i < n; ++i) {
    cin >> ab.at(i).first >> ab.at(i).second;
  }

  ll zero = 0;
  for (int i = 0; i < n; ++i) {
    if (ab.at(i).first < 0 && ab.at(i).second < 0) {
      ab.at(i).first = -ab.at(i).first;
      ab.at(i).second = -ab.at(i).second;
    } else if (ab.at(i).first >= 0 && ab.at(i).second < 0) {
      ab.at(i).first = -ab.at(i).first;
      ab.at(i).second = -ab.at(i).second;
    }
    ll g = gcd(abs(ab.at(i).first), ab.at(i).second);
    if (g == 0)
      continue;
    ab.at(i).first /= g;
    ab.at(i).second /= g;
    if (ab.at(i).first == 0) {
      ab.at(i).second = 1;
    }
    if (ab.at(i).second == 0) {
      ab.at(i).first = 1;
    }
  }

  map<pair<ll, ll>, ll> p, m;
  for (int i = 0; i < n; ++i) {
    if (ab.at(i).first == 0 && ab.at(i).second == 0) {
      ++zero;
      continue;
    }
    p[make_pair(ab.at(i).first, ab.at(i).second)]++;
    if (ab.at(i).first == 0) {
      m[make_pair(1, 0)]++;
    } else if (ab.at(i).second == 0) {
      m[make_pair(0, 1)]++;
    } else {
      if (ab.at(i).first >= 0)
        m[make_pair(-ab.at(i).second, ab.at(i).first)]++;
      else
        m[make_pair(ab.at(i).second, -ab.at(i).first)]++;
    }
  }

  map<pair<ll, ll>, ll> pa;
  for (auto iter = p.begin(); iter != p.end(); ++iter) {
    ll x = iter->second;
    ll y = m[iter->first];
    if (y == 0)
      continue;
    pa[make_pair(min(x, y), max(x, y))]++;
  }

  ModInt<MOD> res(1);
  ll cnt = n;
  for (auto iter = pa.begin(); iter != pa.end(); ++iter) {
    auto pp = iter->first;
    ll x = pp.first, y = pp.second;
    ll c = iter->second / 2;
    assert(2 * c == iter->second);
    for (int i = 0; i < c; ++i) {
      res *= (modpow(ModInt<MOD>(2), x) + modpow(ModInt<MOD>(2), y) - 1);
    }
    cnt -= (x + y) * c;
  }
  res *= modpow(ModInt<MOD>(2), cnt - zero);
  cout << res - 1 + zero << '\\n';
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(20);

  solve();

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;

template <class T> inline bool chmax(T &a, const T &b) {
  if (b > a) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

constexpr int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr double PI = M_PI;

template <int mod> class ModInt {
private:
  long long val;

public:
  ModInt(const long long v = 0) : val(v % mod) {
    if (val < 0)
      val += mod;
  }
  ModInt(const ModInt &v) : val(v.val) {}
  ModInt &operator=(const long long v) {
    val = v;
    return *this;
  }
  ModInt &operator=(const ModInt &v) {
    if (this != &v)
      val = v.val;
    return *this;
  }
  ModInt operator+() const { return ModInt(val); }
  ModInt operator-() const { return ModInt(-val); }
  ModInt operator+(const ModInt &v) const { return ModInt(*this) += v; }
  ModInt operator-(const ModInt &v) const { return ModInt(*this) -= v; }
  ModInt operator*(const ModInt &v) const { return ModInt(*this) *= v; }
  ModInt operator/(const ModInt &v) const { return ModInt(*this) /= v; }
  ModInt &operator+=(const ModInt &v) {
    val += v.val;
    if (val >= mod)
      val -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &v) {
    val -= v.val;
    if (val < 0)
      val += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &v) {
    val *= v.val;
    if (val >= mod)
      val %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &v) {
    val *= v.inverse();
    if (val >= mod)
      val %= mod;
    return *this;
  }
  ModInt &operator++() {
    ++val;
    if (val >= mod)
      val -= mod;
    return *this;
  }
  ModInt &operator--() {
    --val;
    if (val < 0)
      val += mod;
    return *this;
  }
  ModInt operator++(int) {
    ModInt tmp(*this);
    operator++();
    return tmp;
  }
  ModInt operator--(int) {
    ModInt tmp(*this);
    operator--();
    return tmp;
  }
  bool operator==(const ModInt &v) const { return val == v.val; }
  bool operator!=(const ModInt &v) const { return !(*this == v); }
  friend istream &operator>>(istream &s, ModInt &v) {
    long long tmp;
    s >> tmp;
    v = ModInt(tmp);
    return s;
  }
  friend ostream &operator<<(ostream &s, const ModInt &v) { return s << v.val; }
  ModInt inverse() const {
    long long n = val, res = 1;
    while (n > 1) {
      res *= (mod - mod / n);
      res %= mod;
      n = mod % n;
    }
    return ModInt(res);
  }
  friend ModInt modpow(ModInt v, long long n) {
    ModInt res(1);
    for (; n > 0; n >>= 1) {
      if (n & 1)
        res *= v;
      v *= v;
    }
    return res;
  }
};

long long gcd(long long a, long long b) {
  if (a < b)
    std::swap(a, b);
  if (b == 0)
    return a;

  while (b > 0) {
    long long buf = b;
    b = a % b;
    a = buf;
  }
  return a;
}

void solve() {
  ll n;
  cin >> n;
  vector<pair<ll, ll>> ab(n);
  for (int i = 0; i < n; ++i) {
    cin >> ab.at(i).first >> ab.at(i).second;
  }

  ll zero = 0;
  for (int i = 0; i < n; ++i) {
    if (ab.at(i).first < 0 && ab.at(i).second < 0) {
      ab.at(i).first = -ab.at(i).first;
      ab.at(i).second = -ab.at(i).second;
    } else if (ab.at(i).first >= 0 && ab.at(i).second < 0) {
      ab.at(i).first = -ab.at(i).first;
      ab.at(i).second = -ab.at(i).second;
    }
    ll g = gcd(abs(ab.at(i).first), ab.at(i).second);
    if (g == 0)
      continue;
    ab.at(i).first /= g;
    ab.at(i).second /= g;
    if (ab.at(i).first == 0 || ab.at(i).second == 0) {
      ab.at(i).first = abs(ab.at(i).first);
      ab.at(i).second = abs(ab.at(i).second);
    }
  }

  map<pair<ll, ll>, ll> p, m;
  for (int i = 0; i < n; ++i) {
    if (ab.at(i).first == 0 && ab.at(i).second == 0) {
      ++zero;
      continue;
    }
    p[make_pair(ab.at(i).first, ab.at(i).second)]++;
    if (ab.at(i).first >= 0)
      m[make_pair(-ab.at(i).second, ab.at(i).first)]++;
    else
      m[make_pair(ab.at(i).second, -ab.at(i).first)]++;
  }

  map<pair<ll, ll>, ll> pa;
  for (auto iter = p.begin(); iter != p.end(); ++iter) {
    ll x = iter->second;
    ll y = m[iter->first];
    if (y == 0)
      continue;
    pa[make_pair(min(x, y), max(x, y))]++;
  }

  ModInt<MOD> res(1);
  ll cnt = n;
  for (auto iter = pa.begin(); iter != pa.end(); ++iter) {
    auto pp = iter->first;
    ll x = pp.first, y = pp.second;
    ll c = iter->second / 2;
    assert(2 * c == iter->second);
    for (int i = 0; i < c; ++i) {
      res *= (modpow(ModInt<MOD>(2), x) + modpow(ModInt<MOD>(2), y) - 1);
    }
    cnt -= (x + y) * c;
  }
  res *= modpow(ModInt<MOD>(2), cnt - zero);
  cout << res - 1 + zero << '\\n';
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(20);

  solve();

  return 0;
}