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

#include <bits/stdc++.h>

// #undef DEBUG  // Uncomment this line to forcefully disable debug print.
#if DEBUG
template <typename T> void debug(T value) { std::cerr << value; }
template <typename T, typename... Ts> void debug(T value, Ts... args) {
  std::cerr << value << ", ";
  debug(args...);
}
#define dbg(...)                                                               \\
  do {                                                                         \\
    cerr << #__VA_ARGS__ << ": ";                                              \\
    debug(__VA_ARGS__);                                                        \\
    cerr << " (L" << __LINE__ << ")" << endl;                                  \\
  } while (0)
#else
#define dbg(...)
#endif

void read_from_cin() {}
template <typename T, typename... Ts>
void read_from_cin(T &value, Ts &...args) {
  std::cin >> value;
  read_from_cin(args...);
}
#define in(type, ...)                                                          \\
  type __VA_ARGS__;                                                            \\
  read_from_cin(__VA_ARGS__);

template <typename T> void write_to_cout(const T &value) {
  std::cout << value << std::endl;
}
template <typename T, typename... Ts>
void write_to_cout(const T &value, const Ts &...args) {
  std::cout << value << ' ';
  write_to_cout(args...);
}
#define out(...) write_to_cout(__VA_ARGS__);

#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

using ll = long long;

using namespace std;

template <int Mod> class ModInt {
public:
  ModInt() : n_(0) {}
  ModInt(long long n) : n_(n % Mod) {
    if (n_ < 0) {
      // In C++, (-n)%m == -(n%m).
      n_ += Mod;
    }
  }
  ModInt &operator+=(const ModInt &m) {
    n_ += m.n_;
    if (n_ >= Mod) {
      n_ -= Mod;
    }
    return *this;
  }
  ModInt &operator++() { return (*this) += 1; }
  ModInt &operator-=(const ModInt &m) {
    n_ -= m.n_;
    if (n_ < 0) {
      n_ += Mod;
    }
    return *this;
  }
  ModInt &operator--() { return (*this) -= 1; }
  ModInt &operator*=(const ModInt &m) {
    n_ *= m.n_;
    n_ %= Mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &m) {
    *this *= m.Inv();
    return *this;
  }
#define DEFINE_BINARY_OPERATOR(op)                                             \\
  ModInt operator op(const ModInt &m) const { return ModInt(*this) op## = m; }
  DEFINE_BINARY_OPERATOR(+)
  DEFINE_BINARY_OPERATOR(-)
  DEFINE_BINARY_OPERATOR(*)
  DEFINE_BINARY_OPERATOR(/)
#undef DEFINE_BINARY_OPERATOR
#define DEFINE_COMPARISON_OPERATOR(op)                                         \\
  bool operator op(const ModInt &m) const { return n_ op m.n_; }
  DEFINE_COMPARISON_OPERATOR(!=)
  DEFINE_COMPARISON_OPERATOR(<)
  DEFINE_COMPARISON_OPERATOR(<=)
  DEFINE_COMPARISON_OPERATOR(==)
  DEFINE_COMPARISON_OPERATOR(>)
  DEFINE_COMPARISON_OPERATOR(>=)
#undef BDEFINE_COMPARISON_OPERATOR
  ModInt operator-() const { return ModInt(-n_); }
  ModInt Pow(int n) const {
    if (n < 0) {
      return Inv().Pow(-n);
    }
    // a * b ^ n = answer.
    ModInt a = 1, b = *this;
    while (n != 0) {
      if (n & 1) {
        a *= b;
      }
      n /= 2;
      b *= b;
    }
    return a;
  }
  ModInt Inv() const {
    // Compute the inverse based on Fermat's little theorem. Note that this only
    // works when n_ and Mod are relatively prime. The theorem says that
    // n_^(Mod-1) = 1 (mod Mod). So we can compute n_^(Mod-2).
    return Pow(Mod - 2);
  }
  long long value() const { return n_; }

  static ModInt Fact(int n) {
    for (int i = fact_.size(); i <= n; ++i) {
      fact_.push_back(i == 0 ? 1 : fact_.back() * i);
    }
    return fact_[n];
  }
  static ModInt Comb(int n, int k) { return Perm(n, k) / Fact(k); }
  static ModInt CombSlow(int n, int k) { return PermSlow(n, k) / Fact(k); }
  static ModInt Perm(int n, int k) {
#if DEBUG
    assert(n <= 1000000 &&
           "n is too large. If k is small, consider using PermSlow.");
#endif
    return Fact(n) / Fact(n - k);
  }
  static ModInt PermSlow(int n, int k) {
    ModInt p = 1;
    for (int i = 0; i < k; ++i) {
      p *= (n - i);
    }
    return p;
  }

private:
  long long n_;
  static std::vector<ModInt> fact_;
};

template <int Mod> std::vector<ModInt<Mod>> ModInt<Mod>::fact_;

template <int Mod>
std::ostream &operator<<(std::ostream &out, const ModInt<Mod> &m) {
  out << m.value();
  return out;
}

using mint = ModInt<1000000007>;

int main() {
  in(ll, n, k);
  vector<ll> p;
  vector<ll> z;
  vector<ll> m;
  rep(i, n) {
    in(ll, a);
    if (a == 0) {
      z.push_back(0);
    } else if (a > 0) {
      p.push_back(a);
    } else {
      m.push_back(-a);
    }
  }
  bool can_make_positive = false;
  for (int mc = 0; mc <= min<int>(m.size(), k); ++mc) {
    if (p.size() >= (k - mc) && mc % 2 == 0) {
      can_make_positive = true;
    }
  }
  // answer has to be minus or zero
  if (!can_make_positive) {
    // if (k > p.size() && (k - p.size()) % 2 == 1) {
    // can be zero?
    if (!z.empty()) {
      dbg("can be zero");
      out(0);
    } else {
      dbg("has to be minus");
      mint ans = 1;
      rep(i, p.size()) ans *= p[i];
      sort(all(m));
      rep(i, k - p.size()) ans *= m[i];
      out(-ans);
    }
  } else {
    // answer has to be zero?
    if (!z.empty() && k > (p.size() + m.size())) {
      dbg("has to be zero");
      out(0);
    } else {
      mint ans = 1;
      ll pi = 0;
      ll mi = 0;
      sort(all(p), greater());
      sort(all(m), greater());
      while (pi + mi < k) {
        int rk = k - (pi + mi);
        if (rk == 1) {
          assert(pi < p.size());
          ans *= p[pi];
          out(ans);
          return 0;
        }
        if (pi + 1 >= p.size()) {
          assert(mi + 1 < m.size());
          ans *= m[mi] * m[mi + 1];
          mi += 2;
        } else if (mi + 1 >= m.size()) {
          assert(pi + 1 < p.size());
          ans *= p[pi] * p[pi + 1];
          pi += 2;
        } else {
          ll px = p[pi] * p[pi + 1];
          ll mx = m[mi] * m[mi + 1];
          if (px > mx) { // ?
            ans *= p[pi] * p[pi + 1];
            pi += 2;
          } else {
            ans *= m[mi] * m[mi + 1];
            mi += 2;
          }
        }
      }
      out(ans);
    }
  }
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

// #undef DEBUG  // Uncomment this line to forcefully disable debug print.
#if DEBUG
template <typename T> void debug(T value) { std::cerr << value; }
template <typename T, typename... Ts> void debug(T value, Ts... args) {
  std::cerr << value << ", ";
  debug(args...);
}
#define dbg(...)                                                               \\
  do {                                                                         \\
    cerr << #__VA_ARGS__ << ": ";                                              \\
    debug(__VA_ARGS__);                                                        \\
    cerr << " (L" << __LINE__ << ")" << endl;                                  \\
  } while (0)
#else
#define dbg(...)
#endif

void read_from_cin() {}
template <typename T, typename... Ts>
void read_from_cin(T &value, Ts &...args) {
  std::cin >> value;
  read_from_cin(args...);
}
#define in(type, ...)                                                          \\
  type __VA_ARGS__;                                                            \\
  read_from_cin(__VA_ARGS__);

template <typename T> void write_to_cout(const T &value) {
  std::cout << value << std::endl;
}
template <typename T, typename... Ts>
void write_to_cout(const T &value, const Ts &...args) {
  std::cout << value << ' ';
  write_to_cout(args...);
}
#define out(...) write_to_cout(__VA_ARGS__);

#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

using ll = long long;

using namespace std;

template <int Mod> class ModInt {
public:
  ModInt() : n_(0) {}
  ModInt(long long n) : n_(n % Mod) {
    if (n_ < 0) {
      // In C++, (-n)%m == -(n%m).
      n_ += Mod;
    }
  }
  ModInt &operator+=(const ModInt &m) {
    n_ += m.n_;
    if (n_ >= Mod) {
      n_ -= Mod;
    }
    return *this;
  }
  ModInt &operator++() { return (*this) += 1; }
  ModInt &operator-=(const ModInt &m) {
    n_ -= m.n_;
    if (n_ < 0) {
      n_ += Mod;
    }
    return *this;
  }
  ModInt &operator--() { return (*this) -= 1; }
  ModInt &operator*=(const ModInt &m) {
    n_ *= m.n_;
    n_ %= Mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &m) {
    *this *= m.Inv();
    return *this;
  }
#define DEFINE_BINARY_OPERATOR(op)                                             \\
  ModInt operator op(const ModInt &m) const { return ModInt(*this) op## = m; }
  DEFINE_BINARY_OPERATOR(+)
  DEFINE_BINARY_OPERATOR(-)
  DEFINE_BINARY_OPERATOR(*)
  DEFINE_BINARY_OPERATOR(/)
#undef DEFINE_BINARY_OPERATOR
#define DEFINE_COMPARISON_OPERATOR(op)                                         \\
  bool operator op(const ModInt &m) const { return n_ op m.n_; }
  DEFINE_COMPARISON_OPERATOR(!=)
  DEFINE_COMPARISON_OPERATOR(<)
  DEFINE_COMPARISON_OPERATOR(<=)
  DEFINE_COMPARISON_OPERATOR(==)
  DEFINE_COMPARISON_OPERATOR(>)
  DEFINE_COMPARISON_OPERATOR(>=)
#undef BDEFINE_COMPARISON_OPERATOR
  ModInt operator-() const { return ModInt(-n_); }
  ModInt Pow(int n) const {
    if (n < 0) {
      return Inv().Pow(-n);
    }
    // a * b ^ n = answer.
    ModInt a = 1, b = *this;
    while (n != 0) {
      if (n & 1) {
        a *= b;
      }
      n /= 2;
      b *= b;
    }
    return a;
  }
  ModInt Inv() const {
    // Compute the inverse based on Fermat's little theorem. Note that this only
    // works when n_ and Mod are relatively prime. The theorem says that
    // n_^(Mod-1) = 1 (mod Mod). So we can compute n_^(Mod-2).
    return Pow(Mod - 2);
  }
  long long value() const { return n_; }

  static ModInt Fact(int n) {
    for (int i = fact_.size(); i <= n; ++i) {
      fact_.push_back(i == 0 ? 1 : fact_.back() * i);
    }
    return fact_[n];
  }
  static ModInt Comb(int n, int k) { return Perm(n, k) / Fact(k); }
  static ModInt CombSlow(int n, int k) { return PermSlow(n, k) / Fact(k); }
  static ModInt Perm(int n, int k) {
#if DEBUG
    assert(n <= 1000000 &&
           "n is too large. If k is small, consider using PermSlow.");
#endif
    return Fact(n) / Fact(n - k);
  }
  static ModInt PermSlow(int n, int k) {
    ModInt p = 1;
    for (int i = 0; i < k; ++i) {
      p *= (n - i);
    }
    return p;
  }

private:
  long long n_;
  static std::vector<ModInt> fact_;
};

template <int Mod> std::vector<ModInt<Mod>> ModInt<Mod>::fact_;

template <int Mod>
std::ostream &operator<<(std::ostream &out, const ModInt<Mod> &m) {
  out << m.value();
  return out;
}

using mint = ModInt<1000000007>;

int main() {
  in(ll, n, k);
  vector<ll> p;
  vector<ll> z;
  vector<ll> m;
  rep(i, n) {
    in(ll, a);
    if (a == 0) {
      z.push_back(0);
    } else if (a > 0) {
      p.push_back(a);
    } else {
      m.push_back(-a);
    }
  }
  // answer has to be minus or zero
  if (k > p.size() && (k - p.size()) % 2 == 1) {
    // can be zero?
    if (!z.empty()) {
      out(0);
    } else {
      mint ans = 1;
      rep(i, p.size()) ans *= p[i];
      sort(all(m));
      rep(i, k - p.size()) ans *= m[i];
      out(-ans);
    }
  } else {
    // answer has to be zero?
    if (!z.empty() && k > (p.size() * m.size())) {
      out(0);
    } else {
      mint ans = 1;
      ll pi = 0;
      ll mi = 0;
      while (pi + mi < k) {
        int rk = k - (pi + mi);
        if (rk == 1) {
          assert(pi < p.size());
          ans *= p[pi];
          out(ans);
          return 0;
        }
        if (pi + 1 >= p.size()) {
          assert(mi + 1 < m.size());
          ans *= m[mi] * m[mi + 1];
          mi += 2;
        } else if (mi + 1 >= m.size()) {
          assert(pi + 1 < p.size());
          ans *= p[pi] * p[pi + 1];
          pi += 2;
        } else {
          ll px = p[pi] * p[pi + 1];
          ll mx = m[mi] * m[mi + 1];
          if (px > mx) { // ?
            ans *= p[pi] * p[pi + 1];
            pi += 2;
          } else {
            ans *= m[mi] * m[mi + 1];
            mi += 2;
          }
        }
      }
      out(ans);
    }
  }
}