Problem p02679 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
const ll mod = 1000000007;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;

void prvec(vector<ll> vec) { // for debug
  ll n = vec.size();
  cout << "------------------------------------\n";
  rep(i, n) cout << i << " " << vec.at(i) << "\n";
  cout << "------------------------------------\n";
}

void pr2d(vector<vector<ll>> vec) { // for debug
  ll h = vec.size();
  ll w = vec.at(0).size();
  cout << "------------------------------------\n";
  rep(i, h) {
    rep(j, w) { cout << vec.at(i).at(j) << " "; }
    cout << "\n";
  }
  cout << "------------------------------------\n";
}

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

int main() {
  std::ifstream in("sample_01.txt");
  std::cin.rdbuf(in.rdbuf());

  ll n;
  cin >> n;
  map<pair<ll, ll>, ll> mp_plus, mp_minus;
  ll zerocount = 0;
  ll azero = 0, bzero = 0;
  rep(i, n) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zerocount++;
      continue;
    }
    if (b == 0) {
      bzero++;
      continue;
    }
    if (a == 0) {
      azero++;
      continue;
    }
    if ((a > 0 && b > 0) || (a < 0 && b < 0)) {
      a = abs(a), b = abs(b);
      pair<ll, ll> x = make_pair(a / __gcd(a, b), b / __gcd(a, b));
      if (mp_plus.count(x)) {
        mp_plus.at(x)++;
      } else {
        mp_plus[x] = 1;
      }
    } else {
      a = abs(a), b = abs(b);
      pair<ll, ll> x = make_pair(b / __gcd(a, b), a / __gcd(a, b));
      if (mp_minus.count(x)) {
        mp_minus.at(x)++;
      } else {
        mp_minus[x] = 1;
      }
    }
  }
  ll hategaitoucount = 0;
  ll hate_comb = 1;
  for (auto a : mp_plus) {
    if (mp_minus.count(a.first)) {
      hate_comb = hate_comb *
                  ((modpow(2, a.second, mod) - 1) +
                   (modpow(2, mp_minus.at(a.first), mod) - 1) + 1) %
                  mod; // hate_combだけの組み合わせ
      hategaitoucount +=
          a.second + mp_minus.at(a.first); // hateペアになりうるものの数
    }
  }

  ll non_hate = n - hategaitoucount - zerocount - azero - bzero;
  hate_comb = hate_comb *
              ((modpow(2, azero, mod) - 1) + (modpow(2, bzero, mod) - 1) + 1) %
              mod;

  ll ans = modpow(2, non_hate, mod) * hate_comb % mod;
  ans--;
  ans += zerocount;
  if (ans < 0)
    ans += mod;
  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
const ll mod = 1000000007;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;

void prvec(vector<ll> vec) { // for debug
  ll n = vec.size();
  cout << "------------------------------------\n";
  rep(i, n) cout << i << " " << vec.at(i) << "\n";
  cout << "------------------------------------\n";
}

void pr2d(vector<vector<ll>> vec) { // for debug
  ll h = vec.size();
  ll w = vec.at(0).size();
  cout << "------------------------------------\n";
  rep(i, h) {
    rep(j, w) { cout << vec.at(i).at(j) << " "; }
    cout << "\n";
  }
  cout << "------------------------------------\n";
}

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

int main() {
  // std::ifstream in("sample_01.txt");
  // std::cin.rdbuf(in.rdbuf());

  ll n;
  cin >> n;
  map<pair<ll, ll>, ll> mp_plus, mp_minus;
  ll zerocount = 0;
  ll azero = 0, bzero = 0;
  rep(i, n) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zerocount++;
      continue;
    }
    if (b == 0) {
      bzero++;
      continue;
    }
    if (a == 0) {
      azero++;
      continue;
    }
    if ((a > 0 && b > 0) || (a < 0 && b < 0)) {
      a = abs(a), b = abs(b);
      pair<ll, ll> x = make_pair(a / __gcd(a, b), b / __gcd(a, b));
      if (mp_plus.count(x)) {
        mp_plus.at(x)++;
      } else {
        mp_plus[x] = 1;
      }
    } else {
      a = abs(a), b = abs(b);
      pair<ll, ll> x = make_pair(b / __gcd(a, b), a / __gcd(a, b));
      if (mp_minus.count(x)) {
        mp_minus.at(x)++;
      } else {
        mp_minus[x] = 1;
      }
    }
  }
  ll hategaitoucount = 0;
  ll hate_comb = 1;
  for (auto a : mp_plus) {
    if (mp_minus.count(a.first)) {
      hate_comb = hate_comb *
                  ((modpow(2, a.second, mod) - 1) +
                   (modpow(2, mp_minus.at(a.first), mod) - 1) + 1) %
                  mod; // hate_combだけの組み合わせ
      hategaitoucount +=
          a.second + mp_minus.at(a.first); // hateペアになりうるものの数
    }
  }

  ll non_hate = n - hategaitoucount - zerocount - azero - bzero;
  hate_comb = hate_comb *
              ((modpow(2, azero, mod) - 1) + (modpow(2, bzero, mod) - 1) + 1) %
              mod;

  ll ans = modpow(2, non_hate, mod) * hate_comb % mod;
  ans--;
  ans += zerocount;
  if (ans < 0)
    ans += mod;
  cout << ans << endl;

  return 0;
}