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

#include <bits/stdc++.h>

int64_t gcd(int64_t a, int64_t b) {
  if (b < a)
    std::swap(a, b);
  if (a == 0)
    return b;
  return gcd(b % a, a);
}

const int MAX_N = 200005;
const int64_t MOD = 1000000007;
int64_t N;
int64_t as[MAX_N], bs[MAX_N];
std::map<std::pair<int64_t, int64_t>, int64_t> counts1, counts2;
std::set<std::pair<int64_t, int64_t>> seen;

int64_t modpow(int64_t v, int64_t e) {
  if (e == 0)
    return 1;
  if (e == 1)
    return v % MOD;
  int64_t mm = modpow(v, e / 2) % MOD;
  int64_t mmm = (mm * mm) % MOD;
  if (e % 2) {
    return (mmm * v) % MOD;
  }
  return mmm;
}

int main() {
  scanf("%lld", &N);
  int had_zero = 0;
  for (int i = 0; i < N; ++i) {
    scanf("%lld %lld", as + i, bs + i);
    if (bs[i] < 0 || (bs[i] == 0 && as[i] < 0)) {
      as[i] *= -1;
      bs[i] *= -1;
    }
    int64_t g = gcd(std::abs(as[i]), std::abs(bs[i]));
    if (as[i] == 0 && bs[i] == 0) {
      had_zero++;
      i--;
      N--;
      continue;
    }
    // printf("%lld %lld: %lld\\n", as[i], bs[i], g);
    counts1[std::make_pair(as[i] / g, bs[i] / g)]++;
    // counts2[std::make_pair(bs[i]/g, -as[i]/g)]++;
  }
  int64_t val = 1;
  for (auto kv : counts1) {
    auto rev = std::make_pair(-kv.first.second, kv.first.first);
    if (rev.second < 0 || (rev.second == 0 && rev.first < 0)) {
      rev.first *= -1;
      rev.second *= -1;
    }
    if (seen.count(kv.first) || seen.count(rev))
      continue;
    seen.insert(kv.first);
    seen.insert(rev);
    // printf("equiv: %lld %lld: %lld\\n", kv.first.first, kv.first.second,
    // kv.second);
    // printf("rev: %lld %lld: %lld\\n", rev.first, rev.second, counts1[rev]);
    val = (val *
           ((modpow(2, kv.second) + modpow(2, counts1[rev]) - 1 + MOD) % MOD)) %
          MOD;
  }
  val = (val - 1 + MOD + had_zero) % MOD;
  printf("%lld\\n", val);
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

int64_t gcd(int64_t a, int64_t b) {
  if (b < a)
    std::swap(a, b);
  if (a == 0)
    return b;
  return gcd(b % a, a);
}

const int MAX_N = 200005;
const int64_t MOD = 100000007;
int64_t N;
int64_t as[MAX_N], bs[MAX_N];
std::map<std::pair<int64_t, int64_t>, int64_t> counts1, counts2;
std::set<std::pair<int64_t, int64_t>> seen;

int64_t modpow(int64_t v, int64_t e) {
  if (e == 0)
    return 1;
  if (e == 1)
    return v % MOD;
  int64_t mm = modpow(v, e / 2) % MOD;
  int64_t mmm = (mm * mm) % MOD;
  if (e % 2) {
    return (mmm * v) % MOD;
  }
  return mmm;
}

int main() {
  scanf("%lld", &N);
  for (int i = 0; i < N; ++i) {
    scanf("%lld %lld", as + i, bs + i);
    if (bs[i] < 0 || (bs[i] == 0 && as[i] < 0)) {
      as[i] *= -1;
      bs[i] *= -1;
    }
    int64_t g = gcd(std::abs(as[i]), std::abs(bs[i]));
    // printf("%lld %lld: %lld\\n", as[i], bs[i], g);
    counts1[std::make_pair(as[i] / g, bs[i] / g)]++;
    // counts2[std::make_pair(bs[i]/g, -as[i]/g)]++;
  }
  int64_t val = 1;
  for (auto kv : counts1) {
    auto rev = std::make_pair(-kv.first.second, kv.first.first);
    if (rev.second < 0 || (rev.second == 0 && rev.first < 0)) {
      rev.first *= -1;
      rev.second *= -1;
    }
    if (seen.count(kv.first) || seen.count(rev))
      continue;
    seen.insert(kv.first);
    seen.insert(rev);
    // printf("equiv: %lld %lld: %lld\\n", kv.first.first, kv.first.second,
    // kv.second);
    // printf("rev: %lld %lld: %lld\\n", rev.first, rev.second, counts1[rev]);
    val = (val * (modpow(2, kv.second) + modpow(2, counts1[rev]) - 1 + MOD)) %
          MOD;
  }
  val = (val - 1 + MOD) % MOD;
  printf("%lld\\n", val);
}