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

#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
int _P = 1000000007;
long long _gcd(long long a, long long b) {
  a = abs(a);
  b = abs(b);
  if (a > b) {
    long long tmp = a;
    a = b;
    b = tmp;
  }
  if (b == 0)
    return 0;
  while (b %= a) {
    long long tmp = a;
    a = b;
    b = tmp;
  }
  return a;
}
const int magic = 19260817;
struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const pair<T1, T2> &pair) const {
    return std::hash<T1>()(pair.first % magic * magic) +
           std::hash<T2>()(pair.second % magic);
  }
};
template <class T, class P> void addto(T &x, P &p) {
  ++x[p];
  //	if(x.count(p)) ++x[p];
  //	else x[p]=1;
}
long long tpp(int n) {
  long long res = 1;
  long long p = 2;
  while (n > 0) {
    if (n & 1)
      res = (res * p) % _P;
    n >>= 1;
    p = (p * p) % _P;
  }
  return res;
}
int main() {
  //	freopen("\\\\sub1_21.txt", "r", stdin);
  typedef pair<long long, long long> pl;
  int N;
  cin >> N;
  unordered_map<pl, int, pair_hash> pool;
  for (int i = 1; i <= N; ++i) {
    long long a, b;
    cin >> a >> b;
    pl p;
    //		cout << "(a,b) = (" << a << ',' << b << ")\\n";
    if (a == 0) {
      p.first = 0;
      if (b == 0) {
        p.second = 0;
        addto(pool, p);
      } else {
        p.second = 1;
        addto(pool, p);
      }
      continue;
    }
    if (b == 0) {
      p.first = 1;
      p.second = 0;
      addto(pool, p);
      continue;
    }
    long long d = _gcd(a, b);
    if (a < 0) {
      a = -a;
      b = -b;
    }
    p.first = a / d;
    p.second = b / d;
    addto(pool, p);
  }
  vector<vector<long long>> stat;
  unordered_set<pl, pair_hash> flag;
  long long reszero = 0;
  for (auto &x : pool) {
    //		cout << x.first.first << ',' << x.first.second << ','
    //				<< x.second << '\\n';
    if (x.first.first == 0 && x.first.second == 0)
      reszero = x.second;
    else if (flag.count(x.first))
      continue;
    else {
      pl p;
      if (x.first.second <= 0) {
        p.first = -x.first.second;
        p.second = x.first.first;
      } else {
        p.first = x.first.second;
        p.second = -x.first.first;
      }
      //			cout << "p=" << p.first <<','<< p.second <<'\\n';
      flag.insert(p);
      stat.push_back({x.second, pool.count(p) ? pool[p] : 0});
    }
  }
  //	cout << "next" << '\\n';
  long long res = 1;
  for (auto &x : stat) {
    //		cout << x[0] << ',' <<  x[1] << '\\n';
    long long tmp = tpp(x[0]);
    if (x[1])
      tmp = (tmp + tpp(x[1]) - 1) % _P;
    res = (res * tmp) % _P;
    //		cout << "res=" << res << '\\n';
  }
  cout << (_P + res + reszero - 1) % _P << endl;
  return 0;
}

Error: TLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
int _P = 1000000007;
long long _gcd(long long a, long long b) {
  a = abs(a);
  b = abs(b);
  if (a > b) {
    long long tmp = a;
    a = b;
    b = tmp;
  }
  if (b == 0)
    return 0;
  while (b %= a) {
    long long tmp = a;
    a = b;
    b = tmp;
  }
  return a;
}
struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const pair<T1, T2> &pair) const {
    return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
  }
};
template <class T, class P> void addto(T &x, P &p) {
  if (x.count(p))
    ++x[p];
  else
    x[p] = 1;
}
long long tpp(int n) {
  long long res = 1;
  long long p = 2;
  while (n > 0) {
    if (n & 1)
      res = (res * p) % _P;
    n >>= 1;
    p = (p * p) % _P;
  }
  return res;
}
int main() {
  //	freopen("\\\\sub1_21.txt", "r", stdin);
  typedef pair<long long, long long> pl;
  int N;
  cin >> N;
  unordered_map<pl, int, pair_hash> pool;
  for (int i = 1; i <= N; ++i) {
    long long a, b;
    //	cin >> a >> b;
    scanf("%lld%lld", &a, &b);
    pl p;
    //		cout << "(a,b) = (" << a << ',' << b << ")\\n";
    if (a == 0) {
      p.first = 0;
      if (b == 0) {
        p.second = 0;
        addto(pool, p);
      } else {
        p.second = 1;
        addto(pool, p);
      }
      continue;
    }
    if (b == 0) {
      p.first = 1;
      p.second = 0;
      addto(pool, p);
      continue;
    }
    long long d = _gcd(a, b);
    if (a < 0) {
      a = -a;
      b = -b;
    }
    p.first = a / d;
    p.second = b / d;
    addto(pool, p);
  }
  vector<vector<long long>> stat;
  unordered_set<pl, pair_hash> flag;
  long long reszero = 0;
  for (auto &x : pool) {
    //		cout << x.first.first << ',' << x.first.second << ','
    //				<< x.second << '\\n';
    if (x.first.first == 0 && x.first.second == 0)
      reszero = x.second;
    else if (flag.count(x.first))
      continue;
    else {
      pl p;
      if (x.first.second <= 0) {
        p.first = -x.first.second;
        p.second = x.first.first;
      } else {
        p.first = x.first.second;
        p.second = -x.first.first;
      }
      //			cout << "p=" << p.first <<','<< p.second <<'\\n';
      flag.insert(p);
      stat.push_back({x.second, pool.count(p) ? pool[p] : 0});
    }
  }
  //	cout << "next" << '\\n';
  long long res = 1;
  for (auto &x : stat) {
    //		cout << x[0] << ',' <<  x[1] << '\\n';
    long long tmp = tpp(x[0]);
    if (x[1])
      tmp = (tmp + tpp(x[1]) - 1) % _P;
    res = (res * tmp) % _P;
    //		cout << "res=" << res << '\\n';
  }
  cout << (_P + res + reszero - 1) % _P << endl;
  return 0;
}