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

#include <bits/stdc++.h>

using namespace std;

typedef long long lli;

const int N = 200000 + 10;
const int MOD = 1000000007;

map<pair<lli, lli>, int> cnt;
int p[N];

lli gcd(lli a, lli b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

int main() {
  int res, n, s, i;
  lli a, b, d;
  bool neg;
  pair<lli, lli> tmp, tmpr;
  cin >> n;
  p[0] = 1;
  for (i = 1; i <= n; i++)
    p[i] = p[i - 1] * 2 % MOD;
  for (i = 1; i <= n; i++) {
    cin >> a >> b;
    neg = false;
    if (a == 0 && b != 0)
      b = 1;
    else if (a != 0 && b == 0)
      a = 1;
    else if (a < 0 && b < 0) {
      a = -a;
      b = -b;
    } else if (a < 0) {
      a = -a;
      neg = true;
    } else if (b < 0) {
      b = -b;
      neg = true;
    }
    d = gcd(a, b);
    if (d) {
      a /= d;
      b /= d;
    }
    if (neg) {
      tmp = make_pair(-a, b);
      if (cnt.find(tmp) != cnt.end())
        cnt[tmp]++;
      else
        cnt[tmp] = 1;
    } else {
      tmp = make_pair(a, b);
      if (cnt.find(tmp) != cnt.end())
        cnt[tmp]++;
      else
        cnt[tmp] = 1;
    }
  }
  res = 1;
  bool zero = false;
  for (map<pair<lli, lli>, int>::iterator itr = cnt.begin(); itr != cnt.end();
       itr++) {
    tmp = itr->first;
    if (tmp.first == 0 && tmp.second == 0) {
      zero = true;
      continue;
    }
    if (tmp.first == 0 || tmp.second == 0)
      tmpr = make_pair(tmp.second, tmp.first);
    else if (tmp.first > 0)
      tmpr = make_pair(-tmp.second, tmp.first);
    else
      tmpr = make_pair(tmp.second, -tmp.first);
    if (cnt.find(tmpr) != cnt.end()) {
      if (tmpr < tmp)
        continue;
      s = cnt[tmpr];
    } else
      s = 0;
    a = (p[cnt[tmp]] - 1 + MOD) % MOD;
    b = (p[s] - 1 + MOD) % MOD;
    res = 1LL * res * (a + b + 1) % MOD;
    //		cout<<tmp.first<<" "<<tmp.second<<" "<<a<<" "<<b<<"
    //"<<res<<endl;
  }
  //	while (zero);
  if (!zero)
    res = (res - 1 + MOD) % MOD;
  else
    res = (res + cnt[make_pair(0, 0)] - 1) % MOD;
  cout << res << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long lli;

const int N = 200000 + 10;
const int MOD = 1000000007;

map<pair<lli, lli>, int> cnt;
int p[N];

lli gcd(lli a, lli b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

int main() {
  int res, n, s, i;
  lli a, b, d;
  bool neg;
  pair<lli, lli> tmp, tmpr;
  cin >> n;
  p[0] = 1;
  for (i = 1; i <= n; i++)
    p[i] = p[i - 1] * 2 % MOD;
  for (i = 1; i <= n; i++) {
    cin >> a >> b;
    neg = false;
    if (a < 0 && b < 0) {
      a = -a;
      b = -b;
    } else if (a < 0) {
      a = -a;
      neg = true;
    } else if (b < 0) {
      b = -b;
      neg = true;
    }
    d = gcd(a, b);
    if (d) {
      a /= d;
      b /= d;
    }
    if (neg) {
      tmp = make_pair(-a, b);
      if (cnt.find(tmp) != cnt.end())
        cnt[tmp]++;
      else
        cnt[tmp] = 1;
    } else {
      tmp = make_pair(a, b);
      if (cnt.find(tmp) != cnt.end())
        cnt[tmp]++;
      else
        cnt[tmp] = 1;
    }
  }
  res = 1;
  bool zero = false;
  for (map<pair<lli, lli>, int>::iterator itr = cnt.begin(); itr != cnt.end();
       itr++) {
    tmp = itr->first;
    if (tmp.first == 0 && tmp.second == 0) {
      zero = true;
      continue;
    }
    if (tmp.first >= 0)
      tmpr = make_pair(-tmp.second, tmp.first);
    else
      tmpr = make_pair(tmp.second, -tmp.first);
    if (cnt.find(tmpr) != cnt.end()) {
      if (tmpr < tmp)
        continue;
      s = cnt[tmpr];
    } else
      s = 0;
    a = (p[cnt[tmp]] - 1 + MOD) % MOD;
    b = (p[s] - 1 + MOD) % MOD;
    res = 1LL * res * (a + b + 1) % MOD;
    //		cout<<tmp.first<<" "<<tmp.second<<" "<<a<<" "<<b<<"
    //"<<res<<endl;
  }
  while (zero)
    ;
  if (!zero)
    res = (res - 1 + MOD) % MOD;
  cout << res << endl;
  return 0;
}