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

// 問題の URL を書いておく
// https://atcoder.jp/contests/abc168/tasks/abc168_e

#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <vector>
using namespace std;

// #define ENABLE_PRINT

template <typename T> T Input() {
  T v;
  cin >> v;
  return v;
}

template <typename T> vector<T> InputVector(int n) {
  vector<T> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  return v;
}

template <typename T> void InputArray(T *begin, int n) {
  for (int i = 0; i < n; ++i) {
    cin >> begin[i];
  }
}

#if defined(ENABLE_PRINT)

#define Print(v)                                                               \\
  do {                                                                         \\
    cout << #v << ": " << v << endl;                                           \\
  } while (0)

#define PrintVec(v)                                                            \\
  do {                                                                         \\
    for (int __i = 0; __i < v.size(); ++__i) {                                 \\
      cout << #v << "[" << __i << "]: " << v[__i] << endl;                     \\
    }                                                                          \\
  } while (0)

#else

#define Print(v) ((void)0)
#define PrintVec(v) ((void)0)

#endif

template <int Mod> struct MintBase {
  int64_t x; // typedef long long int64_t;
  MintBase(int64_t x = 0) : x((x % Mod + Mod) % Mod) {}
  MintBase operator-() const { return MintBase(-x); }
  MintBase &operator+=(const MintBase a) {
    if ((x += a.x) >= Mod)
      x -= Mod;
    return *this;
  }
  MintBase &operator-=(const MintBase a) {
    if ((x += Mod - a.x) >= Mod)
      x -= Mod;
    return *this;
  }
  MintBase &operator*=(const MintBase a) {
    (x *= a.x) %= Mod;
    return *this;
  }
  MintBase operator+(const MintBase a) const { return MintBase(*this) += a; }
  MintBase operator-(const MintBase a) const { return MintBase(*this) -= a; }
  MintBase operator*(const MintBase a) const { return MintBase(*this) *= a; }
  MintBase pow(int64_t t) const {
    if (!t)
      return 1;
    MintBase a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime Mod
  MintBase inv() const { return pow(Mod - 2); }
  MintBase &operator/=(const MintBase a) { return *this *= a.inv(); }
  MintBase operator/(const MintBase a) const { return MintBase(*this) /= a; }
};

// const int Mod = 1000000007;
// const int Mod = 998244353;

using mint = MintBase<1000000007>;

istream &operator>>(istream &is, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

int64_t gcd(int64_t a, int64_t b) {
  if (a < b)
    return gcd(b, a);
  int64_t r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}

int main(int, const char **) {
  int n;
  cin >> n;
  int zeros = 0;

  struct Key {
    int64_t x;
    int64_t y;
    int64_t z;
    void Dump() { cout << "(" << x << ", " << y << ", " << z << ")" << endl; }
  };

  auto compare = [](const Key &a, const Key &b) -> bool {
    if (a.x == b.x) {
      if (a.y == b.y) {
        return a.z < b.z;
      }
      return a.y < b.y;
    }
    return a.x < b.x;
  };

  map<Key, int64_t, decltype(compare)> t{compare};

  for (int i = 0; i < n; ++i) {
    int64_t a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zeros++;
      continue;
    }

    if (a == 0) {
      //            Key k = {0, b < 0 ? -b : b, b < 0 ? -1 : 1};
      Key k = {0, 1, 1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }

    if (b == 0) {
      //            Key k = {a < 0 ? -a : a, 0, a < 0 ? -1 : 1};
      Key k = {1, 0, -1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }

    auto g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    Key k = {abs(a), abs(b), a * b < 0 ? -1 : 1};
    if (t.find(k) == t.end()) {
      t[k] = 0;
    }
    t[k]++;
  }
#if 0
    for(auto i = t.begin(); i != t.end(); ++i)
    {
        cout << i->second << endl;
    }
#endif
  set<Key, decltype(compare)> done{compare};
  vector<mint> counts;
  for (auto itr = t.begin(); itr != t.end(); ++itr) {
    auto k = itr->first;
    auto v = itr->second;
    if (done.find(k) != done.end()) {
      continue;
    }
    Key tk = {k.y, k.x, -1 * k.z};
    if (t.find(tk) == t.end()) {
      t[tk] = 0;
    }
    auto tv = t[tk];
    mint c = 2;
    c = c.pow(v);
    c -= 1;

    mint tc = 2;
    tc = tc.pow(tv);
    tc -= 1;

    Print(c);
    Print(tc);
    counts.push_back(c + tc + 1);

    done.insert(k);
    done.insert(tk);
  }
  mint ans = 0;
  if (counts.size() > 0) {
    ans = 1;
    for (auto count : counts) {
      ans *= count;
    }
    ans -= 1;
  }
  ans += zeros;

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


Error: 0

Fixed submission:

// 問題の URL を書いておく
// https://atcoder.jp/contests/abc168/tasks/abc168_e

#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <vector>
using namespace std;

// #define ENABLE_PRINT

template <typename T> T Input() {
  T v;
  cin >> v;
  return v;
}

template <typename T> vector<T> InputVector(int n) {
  vector<T> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  return v;
}

template <typename T> void InputArray(T *begin, int n) {
  for (int i = 0; i < n; ++i) {
    cin >> begin[i];
  }
}

#if defined(ENABLE_PRINT)

#define Print(v)                                                               \\
  do {                                                                         \\
    cout << #v << ": " << v << endl;                                           \\
  } while (0)

#define PrintVec(v)                                                            \\
  do {                                                                         \\
    for (int __i = 0; __i < v.size(); ++__i) {                                 \\
      cout << #v << "[" << __i << "]: " << v[__i] << endl;                     \\
    }                                                                          \\
  } while (0)

#else

#define Print(v) ((void)0)
#define PrintVec(v) ((void)0)

#endif

template <int Mod> struct MintBase {
  int64_t x; // typedef long long int64_t;
  MintBase(int64_t x = 0) : x((x % Mod + Mod) % Mod) {}
  MintBase operator-() const { return MintBase(-x); }
  MintBase &operator+=(const MintBase a) {
    if ((x += a.x) >= Mod)
      x -= Mod;
    return *this;
  }
  MintBase &operator-=(const MintBase a) {
    if ((x += Mod - a.x) >= Mod)
      x -= Mod;
    return *this;
  }
  MintBase &operator*=(const MintBase a) {
    (x *= a.x) %= Mod;
    return *this;
  }
  MintBase operator+(const MintBase a) const { return MintBase(*this) += a; }
  MintBase operator-(const MintBase a) const { return MintBase(*this) -= a; }
  MintBase operator*(const MintBase a) const { return MintBase(*this) *= a; }
  MintBase pow(int64_t t) const {
    if (!t)
      return 1;
    MintBase a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime Mod
  MintBase inv() const { return pow(Mod - 2); }
  MintBase &operator/=(const MintBase a) { return *this *= a.inv(); }
  MintBase operator/(const MintBase a) const { return MintBase(*this) /= a; }
};

// const int Mod = 1000000007;
// const int Mod = 998244353;

using mint = MintBase<1000000007>;

istream &operator>>(istream &is, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

int gcd(int a, int b) {
  if (a < b)
    return gcd(b, a);
  int r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}

int main(int argc, const char *argv[]) {
  int n;
  cin >> n;
  int zeros = 0;

  struct Key {
    int x;
    int y;
    int z;
    void Dump() { cout << "(" << x << ", " << y << ", " << z << ")" << endl; }
  };

  auto compare = [](const Key &a, const Key &b) -> bool {
    if (a.x == b.x) {
      if (a.y == b.y) {
        return a.z < b.z;
      }
      return a.y < b.y;
    }
    return a.x < b.x;
  };

  map<Key, int, decltype(compare)> t{compare};

  for (int i = 0; i < n; ++i) {
    int a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zeros++;
      continue;
    }

    if (a == 0) {
      Key k = {0, b < 0 ? -b : b, b < 0 ? -1 : 1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }

    if (b == 0) {
      Key k = {a < 0 ? -a : a, 0, a < 0 ? -1 : 1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }

    auto g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    Key k = {abs(a), abs(b), a * b < 0 ? -1 : 1};
    if (t.find(k) == t.end()) {
      t[k] = 0;
    }
    t[k]++;
  }

  set<Key, decltype(compare)> done{compare};
  vector<mint> counts;
  for (auto itr = t.begin(); itr != t.end(); ++itr) {
    auto k = itr->first;
    auto v = itr->second;
    if (done.find(k) != done.end()) {
      continue;
    }
    Key tk = {k.y, k.x, -1 * k.z};
    if (t.find(tk) == t.end()) {
      t[tk] = 0;
    }
    auto tv = t[tk];
    mint c = 2;
    c = c.pow(v);
    c -= 1;

    mint tc = 2;
    tc = tc.pow(t[tk]);
    tc -= 1;

    counts.push_back(c + tc + 1);

    done.insert(k);
    done.insert(tk);
  }
  mint ans = 0;
  if (counts.size() > 0) {
    ans = 1;
    for (auto count : counts) {
      ans *= count;
    }
    ans -= 1;
  }
  ans += zeros;

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