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

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
#define int long long
using P = pair<int, int>;

const ll mod = 1000000007;
#define MAX_N 2200000
ll f[MAX_N];
ll invf[MAX_N];

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

ll nCm(ll n, ll m) { return ((f[n] * invf[m]) % mod) * invf[n - m] % mod; }

int gcd(int x, int y) {
  if (x % y == 0)
    return y;
  return gcd(y % x, x);
}

map<P, int> mp1, mp2;
int non;
signed main() {
  int n;
  cin >> n;
  rep(i, n) {
    int a, b;
    cin >> a >> b;
    if (a == 0 && b == 0)
      non++;
    else if (a == 0) {
      mp1[P(0, 1)]++;
      mp2[P(1, 0)]++;
    } else if (b == 0) {
      mp1[P(1, 0)]++;
      mp2[P(0, 1)]++;
    }

    else if (a > 0 && b > 0) {
      int hoge = gcd(a, b);
      mp1[P(a / hoge, b / hoge)]++;
      mp2[P(-b / hoge, a / hoge)]++;
    } else if (a > 0 && b < 0) {
      int hoge = gcd(a, -b);
      mp1[P(-a / hoge, -b / hoge)]++;
      mp2[P(-b / hoge, a / hoge)]++;

    } else if (a < 0 && b > 0) {
      int hoge = gcd(-a, b);
      mp1[P(a / hoge, b / hoge)]++;
      mp2[P(b / hoge, -a / hoge)]++;

    } else if (a < 0 && b < 0) {
      int hoge = gcd(-a, -b);
      mp1[P(-a / hoge, -b / hoge)]++;
      mp2[P(b / hoge, -a / hoge)]++;
    }
  }
  int ans = 1;
  for (auto tmp : mp1) {

    auto pr = tmp.first;
    auto p = tmp.second;
    auto q = mp2[pr];

    int res =
        modpow(2ll, p, mod) + modpow(2ll, q, mod) -
        1; // 仲の悪い集合A,Bについて、AとBどちらからもとるようなことがないように選ぶ場合の数
    int a = pr.first, b = pr.second;
    if (a == 0) {
      mp2[P(1, 0)] = 0;
      mp1[P(1, 0)] = 0;

    } else if (b == 0) {
      mp2[P(0, 1)] = 0;
      mp1[P(0, 1)] = 0;
    }
    if (a > 0 && b > 0) {
      mp2[P(-b, a)] = 0;
      mp1[P(-b, a)] = 0;
    } else if (a < 0 && b > 0) {
      mp2[P(b, -a)] = 0;
      mp1[P(b, -a)] = 0;
    }
    res %= mod;

    ans *= res;
    ans = (ans % mod + mod) % mod;
  }
  ans -= 1;   // 一つも選ばない
  ans += non; // ゼロゼロは単体でしか選べない

  cout << (ans % mod + mod) % mod << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
using P = pair<int, int>;
#define int long long

const ll mod = 1000000007;
#define MAX_N 2200000
ll f[MAX_N];
ll invf[MAX_N];

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

ll nCm(ll n, ll m) { return ((f[n] * invf[m]) % mod) * invf[n - m] % mod; }

int gcd(int x, int y) {
  if (x % y == 0)
    return y;
  return gcd(y % x, x);
}

map<P, int> mp1, mp2;
int non;
signed main() {
  int n;
  cin >> n;
  rep(i, n) {
    int a, b;
    cin >> a >> b;
    if (a == 0 && b == 0)
      non++;
    else if (a >= 0 && b >= 0) {
      int hoge = gcd(a, b);
      mp1[P(a / hoge, b / hoge)]++;
      mp2[P(-b / hoge, a / hoge)]++;
    } else if (a >= 0 && b <= 0) {
      int hoge = gcd(a, -b);
      mp1[P(-a / hoge, -b / hoge)]++;
      mp2[P(-b / hoge, a / hoge)]++;

    } else if (a <= 0 && b >= 0) {
      int hoge = gcd(-a, b);
      mp1[P(a / hoge, b / hoge)]++;
      mp2[P(b / hoge, -a / hoge)]++;

    } else if (a <= 0 && b <= 0) {
      int hoge = gcd(-a, -b);
      mp1[P(-a / hoge, -b / hoge)]++;
      mp2[P(b / hoge, -a / hoge)]++;
    }
  }
  int ans = 1;
  for (auto tmp : mp1) {

    auto pr = tmp.first;
    auto p = tmp.second;
    auto q = mp2[pr];

    int res =
        modpow(2ll, p, mod) + modpow(2ll, q, mod) -
        1; // 仲の悪い集合A,Bについて、AとBどちらからもとるようなことがないように選ぶ場合の数
    int a = pr.first, b = pr.second;
    if (a > 0 && b > 0) {
      mp2[P(-b, a)] = 0;
      mp1[P(-b, a)] = 0;
    } else if (a < 0 && b > 0) {
      mp2[P(b, -a)] = 0;
      mp1[P(b, -a)] = 0;
    }

    ans *= res;
    ans = (ans % mod + mod) % mod;
  }
  ans -= 1;   // 一つも選ばない
  ans += non; // ゼロゼロは単体でしか選べない

  cout << (ans % mod + mod) % mod << endl;

  return 0;
}