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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define REP(i, n) for (int64_t i = 0; i < (n); ++i)
#define P pair<int, int>
using ll = int64_t;
using namespace std;
#define ketasuu(n) fixed << setprecision(n)
#define btoe(p) p.begin(), p.end()
#define etob(p) p.rbegin(), p.rend()

// library mod int
template <int mod> struct modint {
  ll x;

  // constructor
  modint(ll x = 0) : x((x % mod + mod) % mod) {}

  // unary operator
  modint operator-() const { return modint(mod - x); }
  modint inv() const { return this->pow(mod - 2); }

  // compound assignment
  modint &operator+=(const modint &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  modint &operator-=(const modint &a) {
    if ((x -= a.x) < 0)
      x += mod;
    return *this;
  }
  modint &operator*=(const modint &a) {
    (x *= a.x) %= mod;
    return *this;
  }
  modint &operator/=(const modint &a) { return *this *= a.inv(); }

  // arithmetic
  //  なぜmodintの後ろに＆を書いたり書かなかったりしてるかの理解ができていない
  // おそらく＆をつけるとポインタで参照しているのでもとの値を書き換えることができる
  // ＆をつけないとコピーを作ってからそれに対して計算するので、もとの値は変更されない
  modint operator-(const modint &a) const { return modint(*this) -= a; }
  modint operator+(const modint &a) const { return modint(*this) += a; }
  modint operator*(const modint &a) const { return modint(*this) *= a; }
  modint operator/(const modint &a) const { return modint(*this) /= a; }
  // n should not be smaller than 0.
  modint pow(ll n) const {
    auto x = modint(1);
    auto m = *this;
    while (n > 0) {
      if (n & 1)
        x *= m;
      n >>= 1;
      m *= m;
    }
    return x;
  }

  // compare
  bool operator==(const modint &a) const { return x == a.x; }
  bool operator!=(const modint &a) const { return x != a.x; }

  // I/O
  friend istream &operator>>(istream &is, modint &a) noexcept {
    return is >> a.x;
  }
  friend ostream &operator<<(ostream &os, const modint &a) noexcept {
    return os << a.x;
  }
};

// modの調整
constexpr int mod = 1e9 + 7;
using mint = modint<mod>;

//////////////////////////////////////////////////////////////////////
// mint power
mint mpow(mint a, mint b) {
  auto x = mint(1), m = a;
  auto n = b.x;
  while (n > 0) {
    if (n & 1)
      x *= m;
    n >>= 1;
    m *= m;
  }
  return x;
}

// combination
vector<mint> mintcombvector;
int startmintcomb(int n) {
  mintcombvector.push_back(0);
  mintcombvector.push_back(1);
  rep(i, n) mintcombvector.push_back(mintcombvector[i + 1] * (i + 2));
  return 0;
}
mint comb(mint a, mint b) {
  if (a.x < b.x || a.x <= 0 || b.x < 0)
    return mint(0);
  if (b.x == 0)
    return mint(1);
  if (a == b)
    return mint(1);
  return mintcombvector[a.x] * (mintcombvector[b.x].inv()) *
         (mintcombvector[a.x - b.x].inv());
}
// combinationを使いたいときは　startmintcomb(n=代入したい数の最大値);
// を始めに打つこと

int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> pp, pm, pz;
  rep(i, n) {
    int a;
    cin >> a;
    if (a > 0) {
      pp.push_back(a);
    } else if (a < 0) {
      pm.push_back(a);
    } else {
      pz.push_back(a);
    }
  }
  if (n == k) {
    mint ans = 1;
    for (auto v : pp)
      ans *= v;
    for (auto v : pm)
      ans *= v;
    for (auto v : pz)
      ans *= v;
    cout << ans << endl;
    return 0;
  }
  // ans is minus
  if (pm.size() == n && k % 2 == 1) {
    sort(etob(pm));
    mint ans = 1;
    rep(i, k) ans *= pm[i];
    cout << ans << endl;
    return 0;
  }

  // ans is zero
  if (pp.size() + pm.size() == k) {
    if (pm.size() % 2 == 1) {
      cout << 0 << endl;
      return 0;
    }
  } else if (pp.size() + pm.size() > k) {
    if (pp.empty() && k % 2 == 1) {
      cout << 0 << endl;
      return 0;
    }
  } else {
    cout << 0 << endl;
    return 0;
  }

  // ans is plus
  vector<ll> candi;
  sort(etob(pp));
  sort(btoe(pm));
  rep(i, pp.size() / 2) { candi.push_back(pp[2 * i] * pp[2 * i + 1]); }
  rep(i, pm.size() / 2) { candi.push_back(pm[2 * i] * pm[2 * i + 1]); }
  sort(etob(candi));
  if (k % 2 == 1) {
    mint ans = pp[0];
    vector<ll> kari;
    rep(i, (pp.size() - 1) / 2) {
      kari.push_back(pp[2 * i + 1] * pp[2 * i + 2]);
    }
    rep(i, pm.size() / 2) { kari.push_back(pm[2 * i] * pm[2 * i + 1]); }
    sort(etob(kari));
    rep(i, (k - 1) / 2) { ans *= kari[i]; }
    cout << ans << endl;
    return 0;
  } else {
    mint ans = 1;
    rep(i, k / 2) { ans *= candi[i]; }
    cout << ans << endl;
    return 0;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define REP(i, n) for (int64_t i = 0; i < (n); ++i)
#define P pair<int, int>
using ll = int64_t;
using namespace std;
#define ketasuu(n) fixed << setprecision(n)
#define btoe(p) p.begin(), p.end()
#define etob(p) p.rbegin(), p.rend()

// library mod int
template <int mod> struct modint {
  ll x;

  // constructor
  modint(ll x = 0) : x((x % mod + mod) % mod) {}

  // unary operator
  modint operator-() const { return modint(mod - x); }
  modint inv() const { return this->pow(mod - 2); }

  // compound assignment
  modint &operator+=(const modint &a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  modint &operator-=(const modint &a) {
    if ((x -= a.x) < 0)
      x += mod;
    return *this;
  }
  modint &operator*=(const modint &a) {
    (x *= a.x) %= mod;
    return *this;
  }
  modint &operator/=(const modint &a) { return *this *= a.inv(); }

  // arithmetic
  //  なぜmodintの後ろに＆を書いたり書かなかったりしてるかの理解ができていない
  // おそらく＆をつけるとポインタで参照しているのでもとの値を書き換えることができる
  // ＆をつけないとコピーを作ってからそれに対して計算するので、もとの値は変更されない
  modint operator-(const modint &a) const { return modint(*this) -= a; }
  modint operator+(const modint &a) const { return modint(*this) += a; }
  modint operator*(const modint &a) const { return modint(*this) *= a; }
  modint operator/(const modint &a) const { return modint(*this) /= a; }
  // n should not be smaller than 0.
  modint pow(ll n) const {
    auto x = modint(1);
    auto m = *this;
    while (n > 0) {
      if (n & 1)
        x *= m;
      n >>= 1;
      m *= m;
    }
    return x;
  }

  // compare
  bool operator==(const modint &a) const { return x == a.x; }
  bool operator!=(const modint &a) const { return x != a.x; }

  // I/O
  friend istream &operator>>(istream &is, modint &a) noexcept {
    return is >> a.x;
  }
  friend ostream &operator<<(ostream &os, const modint &a) noexcept {
    return os << a.x;
  }
};

// modの調整
constexpr int mod = 1e9 + 7;
using mint = modint<mod>;

//////////////////////////////////////////////////////////////////////
// mint power
mint mpow(mint a, mint b) {
  auto x = mint(1), m = a;
  auto n = b.x;
  while (n > 0) {
    if (n & 1)
      x *= m;
    n >>= 1;
    m *= m;
  }
  return x;
}

// combination
vector<mint> mintcombvector;
int startmintcomb(int n) {
  mintcombvector.push_back(0);
  mintcombvector.push_back(1);
  rep(i, n) mintcombvector.push_back(mintcombvector[i + 1] * (i + 2));
  return 0;
}
mint comb(mint a, mint b) {
  if (a.x < b.x || a.x <= 0 || b.x < 0)
    return mint(0);
  if (b.x == 0)
    return mint(1);
  if (a == b)
    return mint(1);
  return mintcombvector[a.x] * (mintcombvector[b.x].inv()) *
         (mintcombvector[a.x - b.x].inv());
}
// combinationを使いたいときは　startmintcomb(n=代入したい数の最大値);
// を始めに打つこと

int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> pp, pm, pz;
  rep(i, n) {
    int a;
    cin >> a;
    if (a > 0) {
      pp.push_back(a);
    } else if (a < 0) {
      pm.push_back(a);
    } else {
      pz.push_back(a);
    }
  }
  if (n == k) {
    mint ans = 1;
    for (auto v : pp)
      ans *= v;
    for (auto v : pm)
      ans *= v;
    for (auto v : pz)
      ans *= v;
    cout << ans << endl;
    return 0;
  }
  // ans is minus
  if (pm.size() == n && k % 2 == 1) {
    sort(etob(pm));
    mint ans = 1;
    rep(i, k) ans *= pm[i];
    cout << ans << endl;
    return 0;
  }

  // ans is zero
  bool ok = false;
  int a = pp.size(), b = pm.size();
  if (k % 2 == 0) {
    if (a % 2 == 0) {
      if (a + (b / 2) * 2 < k)
        ok = true;
    } else {
      if (a - 1 + (b / 2) * 2 < k)
        ok = true;
    }
  } else {
    if (a % 2 == 0) {
      if (a - 1 + (b / 2) * 2 < k)
        ok = true;
    } else {
      if (a + (b / 2) * 2 < k)
        ok = true;
    }
  }
  if (ok) {
    cout << 0 << endl;
    return 0;
  }

  // ans is plus
  vector<ll> candi;
  sort(etob(pp));
  sort(btoe(pm));
  rep(i, pp.size() / 2) { candi.push_back(pp[2 * i] * pp[2 * i + 1]); }
  rep(i, pm.size() / 2) { candi.push_back(pm[2 * i] * pm[2 * i + 1]); }
  sort(etob(candi));
  if (k % 2 == 1) {
    mint ans = pp[0];
    vector<ll> kari;
    rep(i, (pp.size() - 1) / 2) {
      kari.push_back(pp[2 * i + 1] * pp[2 * i + 2]);
    }
    rep(i, pm.size() / 2) { kari.push_back(pm[2 * i] * pm[2 * i + 1]); }
    sort(etob(kari));
    rep(i, (k - 1) / 2) { ans *= kari[i]; }
    cout << ans << endl;
    return 0;
  } else {
    mint ans = 1;
    rep(i, k / 2) { ans *= candi[i]; }
    cout << ans << endl;
    return 0;
  }
}