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

#include <algorithm>
#include <cfloat>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/time.h>
#include <unordered_map>
#include <vector>

#define fs first
#define sc second
// #define endl "\\n"

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef pair<ll, ll> P;

class modInt {
  ll value;
  static const ll mod = 1000000007;

public:
  modInt(ll x = 0) : value{x % mod} {}

  inline modInt &operator+=(modInt x) {
    value = (value + x.value) % mod;
    return *this;
  }

  inline modInt &operator-=(modInt x) {
    value = (value + mod - x.value) % mod;
    return *this;
  }

  inline modInt &operator*=(modInt x) {
    value = (value * x.value) % mod;
    return *this;
  }

  inline modInt operator/=(modInt x) {
    *this *= x.inv();
    return *this;
  }

  inline modInt pow(modInt x, int n) {
    modInt res = modInt(1LL);
    while (n > 0) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }

  inline modInt inv() {
    modInt res = pow(value, mod - 2);
    return res;
  }

  inline ll get() { return value; }
};

modInt operator+(modInt x, modInt y) { return x += y; }

modInt operator-(modInt x, modInt y) { return x -= y; }

modInt operator*(modInt x, modInt y) { return x *= y; }

modInt operator/(modInt x, modInt y) { return x /= y; }

ostream &operator<<(ostream &os, modInt x) { return os << x.get(); }

class modIntCombinations {
  vector<modInt> factArray;

  void make_fact(ll x) {
    for (auto i = factArray.size(); i <= x + 1; i++) {
      modInt y = factArray[i - 1] * i;
      factArray.push_back(y);
    }
  }

public:
  modIntCombinations() { factArray.emplace_back(1); }

  modInt fact(ll x) {
    if (factArray.size() < x + 1) {
      make_fact(x);
    }
    return factArray[x];
  }

  modInt comb(ll n, ll k) {
    if (n < k) {
      return modInt{0};
    } else {
      return fact(n) / fact(k) / fact(n - k);
    }
  }

  modInt perm(ll n, ll k) {
    if (n < k) {
      return modInt{0};
    } else {
      return fact(n) / fact(k);
    }
  }
};

// a と b の最大公約数を返す
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// 素数判定
bool is_prime(ll N) {
  if (N == 1)
    return false;
  for (ll i = 2; i * i <= N; ++i) {
    if (N % i == 0)
      return false;
  }
  return true;
}

// 約数列挙
vector<ll> enum_divisors(ll N) {
  vector<ll> res;
  for (ll i = 1; i * i <= N; ++i) {
    if (N % i == 0) {
      res.push_back(i);
      if (N / i != i)
        res.push_back(N / i);
    }
  }
  sort(res.begin(), res.end());
  return res;
}

// 素因数分解
vector<pair<ll, ll>> prime_factorize(ll N) {
  vector<pair<ll, ll>> res;
  for (ll i = 2; i * i <= N; i++) {
    if (N % i != 0)
      continue;
    ll ex = 0;

    while (N % i == 0) {
      ex++;
      N /= i;
    }

    res.push_back({i, ex});
  }

  if (N != 1)
    res.push_back({N, 1});
  return res;
};

int main() {
  int n;
  cin >> n;
  vector<ll> a, b;
  modInt res2 = 0;
  int count2 = 0;
  for (int i = 0; i < n; i++) {
    ll at, bt;
    cin >> at >> bt;
    if (at == 0 && bt == 0) {
      count2++;
      res2 += 1;
      continue;
    }

    if (at == 0) {
      bt = 1;
      a.push_back(at);
      b.push_back(bt);
      continue;
    } else if (bt == 0) {
      at = 1;
      a.push_back(at);
      b.push_back(bt);
      continue;
    }

    ll sa = 1, sb = 1;
    if (at < 0)
      sa = -1;
    if (bt < 0)
      sb = -1;

    ll g = gcd(sa * at, sb * bt);
    at /= g;
    bt /= g;
    a.push_back(at);
    b.push_back(bt);
  }
  n -= count2;

  map<P, int> mp;
  vector<P> count;
  int index = 0;
  for (int i = 0; i < n; i++) {
    if (mp.find(P(a[i], b[i])) == mp.end()) {
      mp[P(a[i], b[i])] = index;
      mp[P(-a[i], -b[i])] = index;

      mp[P(-b[i], a[i])] = index;
      mp[P(b[i], -a[i])] = index;
      count.emplace_back(P(0, 0));
      if (a[i] == 0 || b[i] == 0) {
        if (a[i] != 0) {
          count[index].fs += 1;
        } else {
          count[index].sc += 1;
        }
      } else if (a[i] * b[i] >= 0) {
        count[index].fs += 1;
      } else {
        count[index].sc += 1;
      }

      index++;
    } else {
      int ind = mp[P(a[i], b[i])];
      if (a[i] == 0 || b[i] == 0) {
        if (a[i] != 0) {
          count[ind].fs += 1;
        } else {
          count[ind].sc += 1;
        }
      } else if (a[i] * b[i] >= 0) {
        count[ind].fs += 1;
      } else {
        count[ind].sc += 1;
      }
    }
  }

  modInt res = 1;
  vector<modInt> eachRes(index, 0);
  modInt mm = 0;
  for (int i = 0; i < index; i++) {
    eachRes[i] += mm.pow(2, count[i].fs) - 1;
    eachRes[i] += mm.pow(2, count[i].sc) - 1;
    eachRes[i] += 1;
  }

  for (int i = 0; i < index; i++) {
    res *= eachRes[i];
  }
  res -= 1; // すべてを選ばないケースを除く
  res += res2;

  cout << res << endl;

  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/time.h>
#include <unordered_map>
#include <vector>

#define fs first
#define sc second
// #define endl "\\n"

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef pair<ll, ll> P;

class modInt {
  ll value;
  static const ll mod = 1000000007;

public:
  modInt(ll x = 0) : value{x % mod} {}

  inline modInt &operator+=(modInt x) {
    value = (value + x.value) % mod;
    return *this;
  }

  inline modInt &operator-=(modInt x) {
    value = (value + mod - x.value) % mod;
    return *this;
  }

  inline modInt &operator*=(modInt x) {
    value = (value * x.value) % mod;
    return *this;
  }

  inline modInt operator/=(modInt x) {
    *this *= x.inv();
    return *this;
  }

  inline modInt pow(modInt x, int n) {
    modInt res = modInt(1LL);
    while (n > 0) {
      if (n & 1)
        res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }

  inline modInt inv() {
    modInt res = pow(value, mod - 2);
    return res;
  }

  inline ll get() { return value; }
};

modInt operator+(modInt x, modInt y) { return x += y; }

modInt operator-(modInt x, modInt y) { return x -= y; }

modInt operator*(modInt x, modInt y) { return x *= y; }

modInt operator/(modInt x, modInt y) { return x /= y; }

ostream &operator<<(ostream &os, modInt x) { return os << x.get(); }

class modIntCombinations {
  vector<modInt> factArray;

  void make_fact(ll x) {
    for (auto i = factArray.size(); i <= x + 1; i++) {
      modInt y = factArray[i - 1] * i;
      factArray.push_back(y);
    }
  }

public:
  modIntCombinations() { factArray.emplace_back(1); }

  modInt fact(ll x) {
    if (factArray.size() < x + 1) {
      make_fact(x);
    }
    return factArray[x];
  }

  modInt comb(ll n, ll k) {
    if (n < k) {
      return modInt{0};
    } else {
      return fact(n) / fact(k) / fact(n - k);
    }
  }

  modInt perm(ll n, ll k) {
    if (n < k) {
      return modInt{0};
    } else {
      return fact(n) / fact(k);
    }
  }
};

// a と b の最大公約数を返す
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// 素数判定
bool is_prime(ll N) {
  if (N == 1)
    return false;
  for (ll i = 2; i * i <= N; ++i) {
    if (N % i == 0)
      return false;
  }
  return true;
}

// 約数列挙
vector<ll> enum_divisors(ll N) {
  vector<ll> res;
  for (ll i = 1; i * i <= N; ++i) {
    if (N % i == 0) {
      res.push_back(i);
      if (N / i != i)
        res.push_back(N / i);
    }
  }
  sort(res.begin(), res.end());
  return res;
}

// 素因数分解
vector<pair<ll, ll>> prime_factorize(ll N) {
  vector<pair<ll, ll>> res;
  for (ll i = 2; i * i <= N; i++) {
    if (N % i != 0)
      continue;
    ll ex = 0;

    while (N % i == 0) {
      ex++;
      N /= i;
    }

    res.push_back({i, ex});
  }

  if (N != 1)
    res.push_back({N, 1});
  return res;
};

int main() {
  int n;
  cin >> n;
  vector<ll> a, b;
  modInt res2 = 0;
  for (int i = 0; i < n; i++) {
    ll at, bt;
    cin >> at >> bt;
    if (at == 0 && bt == 0) {
      n--;
      res2 += 1;
      continue;
    }

    if (at == 0) {
      bt = 1;
      a.push_back(at);
      b.push_back(bt);
      continue;
    } else if (bt == 0) {
      at = 1;
      a.push_back(at);
      b.push_back(bt);
      continue;
    }

    ll sa = 1, sb = 1;
    if (at < 0)
      sa = -1;
    if (bt < 0)
      sb = -1;

    ll g = gcd(sa * at, sb * bt);
    at /= g;
    bt /= g;
    a.push_back(at);
    b.push_back(bt);
  }

  map<P, int> mp;
  vector<P> count;
  int index = 0;
  for (int i = 0; i < n; i++) {
    if (mp.find(P(a[i], b[i])) == mp.end()) {
      mp[P(a[i], b[i])] = index;
      mp[P(-a[i], -b[i])] = index;

      mp[P(-b[i], a[i])] = index;
      mp[P(b[i], -a[i])] = index;
      count.emplace_back(P(0, 0));
      if (a[i] == 0 || b[i] == 0) {
        if (a[i] != 0) {
          count[index].fs += 1;
        } else {
          count[index].sc += 1;
        }
      } else if (a[i] * b[i] >= 0) {
        count[index].fs += 1;
      } else {
        count[index].sc += 1;
      }

      index++;
    } else {
      int ind = mp[P(a[i], b[i])];
      if (a[i] == 0 || b[i] == 0) {
        if (a[i] != 0) {
          count[ind].fs += 1;
        } else {
          count[ind].sc += 1;
        }
      } else if (a[i] * b[i] >= 0) {
        count[ind].fs += 1;
      } else {
        count[ind].sc += 1;
      }
    }
  }

  modInt res = 1;
  vector<modInt> eachRes(index, 0);
  modInt mm = 0;
  for (int i = 0; i < index; i++) {
    eachRes[i] += mm.pow(2, count[i].fs) - 1;
    eachRes[i] += mm.pow(2, count[i].sc) - 1;
    eachRes[i] += 1;
  }

  for (int i = 0; i < index; i++) {
    res *= eachRes[i];
  }
  res -= 1; // すべてを選ばないケースを除く
  res += res2;

  cout << res << endl;

  return 0;
}