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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <queue>
#include <set>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;

const ll MOD = 1000000007;

ll mod_pow(ll x, ll n, ll mod = MOD) {
  ll res = 1;

  while (n > 0) {
    if (n & 1) {
      res = res * x % mod;
    }

    x = x * x % mod;
    n >>= 1;
  }

  return res;
}

class Rational {
public:
  ll a;
  ll b;

  Rational(ll a, ll b) {
    ll g = gcd(a, b);

    if (g != 0) {
      this->a = a / g;
      this->b = b / g;
    } else {
      this->a = a;
      this->b = b;
    }
  }

private:
  ll gcd(ll a, ll b) {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
};

int main() {
  int N;
  cin >> N;

  map<ll, map<ll, ll>> counter;
  vector<Rational> R;
  ll A, B;
  ll Z = 0;
  for (int i = 0; i < N; ++i) {
    cin >> A >> B;
    Rational r(A, B);

    if (A == 0 && B == 0) {
      Z++;
      R.push_back(r);
      continue;
    }

    if (r.b < 0) {
      r.a *= -1;
      r.b *= -1;
    } else if (r.b == 0) {
      r.a = 1;
    } else if (r.a == 0) {
      r.b = 1;
    }

    counter[r.a][r.b]++;
    R.push_back(r);
  }

  map<ll, map<ll, bool>> checked;
  ll ans = 1;

  for (int i = 0; i < N; ++i) {
    Rational r = R[i];

    if (r.a == 0 && r.b == 0)
      continue;
    if (checked[r.a][r.b])
      continue;
    checked[r.a][r.b] = true;

    ll s = counter[r.a][r.b];
    ll t = 0;

    if (r.b == 0) {
      t = counter[0][1];
      checked[0][1] = true;
    } else if (r.a == 0) {
      t = counter[1][0];
      checked[1][0] = true;
    } else if (r.a < 0) {
      t = counter[r.b][-r.a];
      checked[r.b][-r.a] = true;
    } else {
      t = counter[-r.b][r.a];
      checked[-r.b][r.a] = true;
    }

    ll v = (mod_pow(2, s) + mod_pow(2, t) - 1);
    ans *= v;
    ans %= MOD;

    fprintf(stderr, "[%lld/%lld], %d: s: %lld, t: %lld, ans: %lld\\n", r.a, r.b,
            i, s, t, ans);
  }

  fprintf(stderr, "Z = %lld\\n", Z);
  ans += (Z - 1);
  if (ans < 0)
    ans += MOD;
  cout << ans << endl;

  return 0;
}


Error: 0
0: s: 1, t: 1
1: s: 1, t: 0


Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <queue>
#include <set>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;

const ll MOD = 1000000007;

ll mod_pow(ll x, ll n, ll mod = MOD) {
  ll res = 1;

  while (n > 0) {
    if (n & 1) {
      res = res * x % mod;
    }

    x = x * x % mod;
    n >>= 1;
  }

  return res;
}

class Rational {
public:
  int a;
  int b;

  Rational(int a, int b) {
    int g = gcd(a, b);

    if (g != 0) {
      this->a = a / g;
      this->b = b / g;
    } else {
      this->a = a;
      this->b = b;
    }
  }

private:
  int gcd(int a, int b) {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
};

int main() {
  int N;
  cin >> N;

  map<ll, map<ll, int>> counter;
  vector<Rational> R;
  int A, B;
  int Z = 0;
  for (int i = 0; i < N; ++i) {
    cin >> A >> B;

    if (A == 0 && B == 0) {
      Z++;
    }

    Rational r(A, B);

    if (r.b < 0) {
      r.a *= -1;
      r.b *= -1;
    } else if (r.b == 0) {
      r.a = 1;
    }

    R.push_back(r);
    counter[r.a][r.b]++;
  }

  map<ll, map<ll, bool>> checked;
  ll ans = 1;

  for (int i = 0; i < N; ++i) {
    Rational r = R[i];

    if (r.a == 0 && r.b == 0)
      continue;
    if (checked[r.a][r.b])
      continue;
    checked[r.a][r.b] = true;

    ll s = counter[r.a][r.b];
    ll t = 0;

    if (r.b == 0) {
      t = counter[1][0];
      checked[1][0] = true;
    } else if (r.a < 0) {
      t = counter[r.b][-r.a];
      checked[r.b][-r.a] = true;
    } else {
      t = counter[-r.b][r.a];
      checked[-r.b][r.a] = true;
    }

    ans *= (mod_pow(2, s) + mod_pow(2, t) - 1);
    ans %= MOD;

    fprintf(stderr, "%d: s: %lld, t: %lld\\n", i, s, t);
  }

  cout << (ans - (Z + 1)) % MOD << endl;

  return 0;
}