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

#include <bits/stdc++.h>
using namespace std;

#include <bits/stdc++.h>
using namespace std;

constexpr int64_t MOD = 1'000'000'007;
/* 剰余環 Z/nZ */
struct mint { // Z/nZ に関する演算(n:素数の場合は除算も)をサポートする構造体
  int64_t rep; // 出力すべき代表元 rep \\in {0,1,..,MOD- 1}
  mint(int64_t x = 0) : rep(((x % MOD) + MOD) % MOD) {}
  mint operator-() const { return mint(-rep); }
  mint &operator+=(const mint &x) {
    rep += x.rep;
    if (rep >= MOD)
      rep -= MOD;
    return *this;
  }
  mint &operator-=(const mint &x) {
    rep -= x.rep;
    if (rep < 0)
      rep += MOD;
    return *this;
  }
  mint &operator*=(const mint &x) {
    rep *= x.rep;
    rep %= MOD;
    return *this;
  }
  mint operator+(const mint x) const {
    mint ans(*this);
    ans += x;
    return ans;
  }
  mint operator-(const mint x) const {
    mint ans(*this);
    ans -= x;
    return ans;
  }
  mint operator*(const mint x) const {
    mint ans(*this);
    ans *= x;
    return ans;
  }
  bool operator==(const mint x) const { return rep == x.rep; }
  bool operator!=(const mint x) const { return rep != x.rep; }

  mint pow(int64_t d) const {
    assert(d >= 0); // ここで引っかかったら this.pow(d)= 0 or this.pow(-d).inv()
                    // のどちらかを選べ
    assert(!(*this == 0 &&
             d == 0)); //   this.pow(d)= 0 or 1           　 のどちらかを選べ
    mint ans = 1;
    mint x = *this;
    while (d > 0) {
      if (d & 1) {
        ans *= x;
      }
      d >>= 1;
      x *= x;
    }

    return ans;
  }

  friend istream &operator>>(istream &is, mint &x) noexcept {
    int64_t a;
    is >> a;
    x = a;
    return is;
  }
  friend ostream &operator<<(ostream &os, const mint &x) noexcept {
    return os << x.rep;
  }
  // MOD が素数(<=> Z/nZ が体)のとき
  mint inv() const { return pow(MOD - 2); }
  mint &operator/=(const mint &x) {
    *this *= x.inv();
    return *this;
  }
  mint operator/(const mint x) const {
    mint ans(*this);
    ans /= x;
    return ans;
  }
};
// ^^^ テンプレここまで ^^^

mint solve_both(const vector<int64_t> &pos, const vector<int64_t> &nonpos,
                int K) {
  const int posN = (int)pos.size();
  const int npN = (int)nonpos.size();

  int offset = (posN + npN == K) ? posN : (K % 2 == 0) ? 0 : 1;
  mint ans = 1;
  for (int posPick = offset; posPick <= posN; posPick += 2) {
    int npPick = K - posPick;
    if (npPick > npN) {
      continue;
    } else {
      if (posPick + 2 <= posN && npPick >= 2 &&
          pos.at(posPick) * pos.at(posPick + 1) >=
              nonpos.at(npPick - 1) * nonpos.at(npPick - 2)) {
        continue;
      } else {
        for (int i_p = 0; i_p < posPick; i_p++) {
          ans *= pos.at(i_p);
        }
        for (int i_np = 0; i_np < npPick; i_np++) {
          ans *= nonpos.at(i_np);
        }

        break;
      }
    }
  }

  return ans;
}

mint solve_np(const vector<int64_t> &nonpos, int K) {
  const int npN = (int)nonpos.size();

  mint ans = 1;
  for (int i = npN - 1; i >= npN - K; i--) {
    ans *= (mint)nonpos.at(i);
  }

  return ans;
}

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

  vector<int64_t> pos;
  vector<int64_t> nonpos;
  int64_t buf;
  for (int i = 0; i < N; i++) {
    cin >> buf;
    if (buf > 0) {
      pos.emplace_back(buf);
    } else {
      nonpos.emplace_back(buf);
    }
  }
  // 絶対値の降順にソート
  sort(pos.begin(), pos.end(), greater<int64_t>());
  sort(nonpos.begin(), nonpos.end());

  mint ans = (!pos.empty() || K % 2 == 0) ? solve_both(pos, nonpos, K)
                                          : solve_np(nonpos, K);

  cout << ans << endl;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#include <bits/stdc++.h>
using namespace std;

constexpr int64_t MOD = 1'000'000'007;
/* 剰余環 Z/nZ */
struct mint { // Z/nZ に関する演算(n:素数の場合は除算も)をサポートする構造体
  int64_t rep; // 出力すべき代表元 rep \\in {0,1,..,MOD- 1}
  mint(int64_t x = 0) : rep(((x % MOD) + MOD) % MOD) {}
  mint operator-() const { return mint(-rep); }
  mint &operator+=(const mint &x) {
    rep += x.rep;
    if (rep >= MOD)
      rep -= MOD;
    return *this;
  }
  mint &operator-=(const mint &x) {
    rep -= x.rep;
    if (rep < 0)
      rep += MOD;
    return *this;
  }
  mint &operator*=(const mint &x) {
    rep *= x.rep;
    rep %= MOD;
    return *this;
  }
  mint operator+(const mint x) const {
    mint ans(*this);
    ans += x;
    return ans;
  }
  mint operator-(const mint x) const {
    mint ans(*this);
    ans -= x;
    return ans;
  }
  mint operator*(const mint x) const {
    mint ans(*this);
    ans *= x;
    return ans;
  }
  bool operator==(const mint x) const { return rep == x.rep; }
  bool operator!=(const mint x) const { return rep != x.rep; }

  mint pow(int64_t d) const {
    assert(d >= 0); // ここで引っかかったら this.pow(d)= 0 or this.pow(-d).inv()
                    // のどちらかを選べ
    assert(!(*this == 0 &&
             d == 0)); //   this.pow(d)= 0 or 1           　 のどちらかを選べ
    mint ans = 1;
    mint x = *this;
    while (d > 0) {
      if (d & 1) {
        ans *= x;
      }
      d >>= 1;
      x *= x;
    }

    return ans;
  }

  friend istream &operator>>(istream &is, mint &x) noexcept {
    int64_t a;
    is >> a;
    x = a;
    return is;
  }
  friend ostream &operator<<(ostream &os, const mint &x) noexcept {
    return os << x.rep;
  }
  // MOD が素数(<=> Z/nZ が体)のとき
  mint inv() const { return pow(MOD - 2); }
  mint &operator/=(const mint &x) {
    *this *= x.inv();
    return *this;
  }
  mint operator/(const mint x) const {
    mint ans(*this);
    ans /= x;
    return ans;
  }
};
// ^^^ テンプレここまで ^^^

mint solve_pos(const vector<int64_t> &pos, const vector<int64_t> &nonpos,
               int K) {
  const int posN = (int)pos.size();
  const int npN = (int)nonpos.size();

  int offset = (K % 2 == 0) ? 0 : 1;
  mint ans = 1;
  bool probe = false;
  for (int posPick = offset; posPick <= posN; posPick += 2) {
    int npPick = K - posPick;
    if (npPick > npN) {
      continue;
    } else {
      if (posPick + 1 < posN && npPick >= 2 &&
          pos.at(posPick) * pos.at(posPick + 1) >=
              nonpos.at(npPick - 1) * nonpos.at(npPick - 2)) {
        continue;
      } else {
        probe = true;
        for (int i_p = 0; i_p < posPick; i_p++) {
          ans *= pos.at(i_p);
        }
        for (int i_np = 0; i_np < npPick; i_np++) {
          ans *= nonpos.at(i_np);
        }

        break;
      }
    }
  }
  assert(probe);
  return ans;
}

mint solve_np(const vector<int64_t> &nonpos, int K) {
  const int npN = (int)nonpos.size();

  mint ans = 1;
  for (int i = npN - 1; i >= npN - K; i--) {
    ans *= (mint)nonpos.at(i);
  }

  return ans;
}

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

  vector<int64_t> pos;
  vector<int64_t> nonpos;
  int64_t buf;
  for (int i = 0; i < N; i++) {
    cin >> buf;
    if (buf > 0) {
      pos.emplace_back(buf);
    } else {
      nonpos.emplace_back(buf);
    }
  }
  // 絶対値の降順にソート
  sort(pos.begin(), pos.end(), greater<int64_t>());
  sort(nonpos.begin(), nonpos.end());

  mint ans = (!pos.empty() || K % 2 == 0) ? solve_pos(pos, nonpos, K)
                                          : solve_np(nonpos, K);

  cout << ans << endl;
}