Problem p02679 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const ll MOD = 1e9 + 7;

struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const std::pair<T1, T2> &pair) const {
    return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
  }
};
unordered_map<ll, ll> memo;
ll mypow2(ll y) {
  if (y == 0)
    return 1;
  else if (y == 1)
    return 2;
  else {
    auto it = memo.find(y);
    if (it != memo.end())
      return it->second;
    else {
      if (y % 2 == 1)
        return memo[y] = 2 * mypow2(y - 1) % MOD;
      else {
        auto ans = mypow2(y / 2);
        return memo[y] = ans * ans % MOD;
      }
    }
  }
}

int main() {
  int N;
  cin >> N;
  // unordered_map<pair<ll, ll>, ll, pair_hash> slopeCount;
  map<pair<ll, ll>, ll> slopeCount;
  ll zeroCount = 0;
  for (int i = 0; i < N; ++i) {
    ll A, B;
    cin >> A >> B;
    if (A == 0 && B == 0) {
      ++zeroCount;
    } else {
      auto gcdAB = __gcd(abs(A), abs(B));
      if (B < 0)
        ++slopeCount[{-A / gcdAB, -B / gcdAB}];
      else
        ++slopeCount[{A / gcdAB, B / gcdAB}];
    }
  }
  // unordered_set<pair<ll, ll>, pair_hash> seen;
  set<pair<ll, ll>> seen;
  ll ans = 1;
  for (const auto &p : slopeCount) {
    const auto &slope = p.first;
    // cout << slope.first << " " << slope.second << " " << p.second
    //      << endl;
    if (seen.find(slope) == seen.end()) {
      pair<ll, ll> vertical;
      if (slope.first == 0) {
        vertical = {1, 0};
      } else if (slope.second == 0) {
        vertical = {0, 1};
      } else if (slope.first < 0) {
        vertical = {slope.second, -slope.first};
      } else {
        vertical = {-slope.second, slope.first};
      }
      auto it = slopeCount.find(vertical);
      if (it != slopeCount.end()) {
        ans *= (mypow2(it->second) + mypow2(p.second) - 1);
        ans %= MOD;
        seen.insert(vertical);
      } else {
        ans *= mypow2(p.second);
        ans %= MOD;
      }
    }
  }
  ans -= 1;
  if (ans < 0)
    ans += MOD;
  ans += zeroCount;
  ans %= MOD;

  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const ll MOD = 1e9 + 7;

struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const std::pair<T1, T2> &pair) const {
    return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
  }
};
unordered_map<ll, ll> memo;
ll mypow2(ll y) {
  if (y == 0)
    return 1;
  else if (y == 1)
    return 2;
  else {
    auto it = memo.find(y);
    if (it != memo.end())
      return it->second;
    else {
      if (y % 2 == 1)
        return memo[y] = 2 * mypow2(y - 1) % MOD;
      else {
        auto ans = mypow2(y / 2);
        return memo[y] = ans * ans % MOD;
      }
    }
  }
}

int main() {
  int N;
  cin >> N;
  unordered_map<pair<ll, ll>, ll, pair_hash> slopeCount;
  ll zeroCount = 0;
  for (int i = 0; i < N; ++i) {
    ll A, B;
    cin >> A >> B;
    if (A == 0 && B == 0) {
      ++zeroCount;
    } else {
      auto gcdAB = __gcd(abs(A), abs(B));
      if (B < 0)
        ++slopeCount[{-A / gcdAB, -B / gcdAB}];
      else
        ++slopeCount[{A / gcdAB, B / gcdAB}];
    }
  }
  unordered_set<pair<ll, ll>, pair_hash> seen;
  ll ans = 1;
  for (const auto &p : slopeCount) {
    const auto &slope = p.first;
    // cout << slope.first << " " << slope.second << " " << p.second
    //      << endl;
    if (seen.find(slope) == seen.end()) {
      pair<ll, ll> vertical;
      if (slope.first == 0) {
        vertical = {1, 0};
      } else if (slope.second == 0) {
        vertical = {0, 1};
      } else if (slope.first < 0) {
        vertical = {slope.second, -slope.first};
      } else {
        vertical = {-slope.second, slope.first};
      }
      auto it = slopeCount.find(vertical);
      if (it != slopeCount.end()) {
        ans *= (mypow2(it->second) + mypow2(p.second) - 1);
        ans %= MOD;
        seen.insert(vertical);
      } else {
        ans *= mypow2(p.second);
        ans %= MOD;
      }
    }
  }
  ans -= 1;
  if (ans < 0)
    ans += MOD;
  ans += zeroCount;
  ans %= MOD;

  cout << ans << endl;
  return 0;
}