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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> P;
const ll MOD = 1000000007;
const ll MAX_N = 500010;
const ll INF = 999999999999;

map<P, ll> mp;
map<P, bool> used;

ll gcd(ll a, ll b) {
  ll M = max(a, b);
  ll m = min(a, b);
  if (m == 0) {
    return M;
  }
  return gcd(m, M % m);
}

ll modpow(ll a, ll n, ll mod) {
  ll ret = 1;
  while (n > 0) {
    if (n & 1)
      ret = ret * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return ret;
}

int main() {
  int n;
  cin >> n;

  ll zero = 0;
  for (int i = 0; i < n; i++) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zero++;
      continue;
    }
    ll g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    if (a >= 0 && b <= 0) {
      mp[P(-a, -b)]++;
    } else if (a <= 0 && b <= 0) {
      mp[P(-a, -b)]++;
    } else {
      mp[P(a, b)]++;
    }
  }

  if (zero == n) {
    cout << n << endl;
    return 0;
  }

  ll ans = 1;
  for (auto p : mp) {
    P key = p.first;
    // cout<<key.first<<","<<key.second<<":"<<p.second<<endl;
    if (!used[P(key.first, key.second)]) {
      if (key.first >= 0 && key.second >= 0) {
        ll buf = modpow(2, p.second, MOD) +
                 modpow(2, mp[P(-key.second, key.first)], MOD) - 1;
        buf %= MOD;
        ans *= buf;
        ans %= MOD;
        used[P(key.first, key.second)] = true;
        used[P(-key.second, key.first)] = true;
      } else {
        ll buf = modpow(2, p.second, MOD) +
                 modpow(2, mp[P(key.second, -key.first)], MOD) - 1;
        buf %= MOD;
        ans *= buf;
        ans %= MOD;
        used[P(key.first, key.second)] = true;
        used[P(key.second, -key.first)] = true;
      }
    }
    // cout<<ans<<endl;
  }
  ans += zero;
  ans--;
  ans = (ans + MOD) % MOD;
  cout << ans << endl;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> P;
const ll MOD = 1000000007;
const ll MAX_N = 500010;
const ll INF = 999999999999;

map<P, ll> mp;
map<P, bool> used;

ll gcd(ll a, ll b) {
  ll M = max(a, b);
  ll m = min(a, b);
  if (m == 0) {
    return M;
  }
  return gcd(m, M % m);
}

ll modpow(ll a, ll n, ll mod) {
  ll ret = 1;
  while (n > 0) {
    if (n & 1)
      ret = ret * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return ret;
}

int main() {
  int n;
  cin >> n;

  ll zero = 0;
  for (int i = 0; i < n; i++) {
    ll a, b;
    cin >> a >> b;
    ll g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    if (a == 0 && b == 0) {
      zero++;
    } else if (a >= 0 && b <= 0) {
      mp[P(-a, -b)]++;
    } else if (a <= 0 && b <= 0) {
      mp[P(-a, -b)]++;
    } else {
      mp[P(a, b)]++;
    }
  }

  ll ans = 1;
  for (auto p : mp) {
    P key = p.first;
    // cout<<key.first<<","<<key.second<<":"<<p.second<<endl;
    if (!used[P(key.first, key.second)]) {
      if (key.first >= 0 && key.second >= 0) {
        ans *= modpow(2, p.second, MOD) +
               modpow(2, mp[P(-key.second, key.first)], MOD) - 1;
        ans %= MOD;
        used[P(key.first, key.second)] = true;
        used[P(-key.second, key.first)] = true;
      } else {
        ans *= modpow(2, p.second, MOD) +
               modpow(2, mp[P(key.second, -key.first)], MOD) - 1;
        ans %= MOD;
        used[P(key.first, key.second)] = true;
        used[P(key.second, -key.first)] = true;
      }
    }
    // cout<<ans<<endl;
  }
  ans += zero;
  ans--;
  cout << ans << endl;
}