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

#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, int>;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;

const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream &operator>>(istream &is, mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> a(n);
  vector<ll> plus, minus;
  rep(i, n) {
    cin >> a[i];
    if (a[i] < 0)
      minus.push_back(a[i]);
    else
      plus.push_back(a[i]);
  }
  mint ans = 1;
  if (n == k) {
    rep(i, n) ans *= a[i];
    cout << ans << endl;
    return 0;
  }
  int ps = plus.size();
  int ms = minus.size();
  bool ok = false;
  if (ps != 0)
    ok = true; // マイナスから選ばざるを得ないが,
               // プラスが一つ以上あればマイナスを偶数個選ぶことが出来る
  else if (k % 2 == 0)
    ok = true; // 全ての要素がマイナスだが, kが偶数のため答えはプラスにできる
  else
    ok =
        false; // プラスの数が0個で、kが奇数の場合はどうしても答えはマイナスになる

  if (!ok) {
    sort(a.begin(), a.end(), [](ll x, ll y) {
      return abs(x) < abs(y);
    }); // 絶対値の小さい順に並べる
    rep(i, k) ans *= a[i];
    cout << ans << endl;
    return 0;
  }
  // 答えをプラスにできる場合はマイナスを偶数個選ばなければならない。
  sort(plus.begin(), plus.end());     // .backが最大値
  sort(minus.rbegin(), minus.rend()); // .backが最小値(絶対値で最大値)
  if (ps == 0) {
    // プラスが0個だった場合で答えが正になるのはマイナスが偶数個であるため、マイナスからすべて選んでOK.
    rep(i, k) {
      ans *= minus.back();
      minus.pop_back();
    }
  } else if (ps == 1) {
    if (k % 2 == 1) {
      ans *= plus.back();
      k--;
    }
    rep(i, k) {
      ans *= minus.back();
      minus.pop_back();
    }
  } else if (2 <= ms) {
    if (k % 2 == 1) {
      ans *= plus.back();
      plus.pop_back();
      k--;
    }
    rep(i, k / 2) {
      if (2 <= plus.size() && 2 <= minus.size()) {
        ll p = plus.back();
        p *= plus[plus.size() - 2];
        ll m = minus.back();
        m *= minus[minus.size() - 2];
        if (p < m) {
          ans *= minus.back();
          minus.pop_back();
          ans *= minus.back();
          minus.pop_back();
        } else {
          ans *= plus.back();
          plus.pop_back();
          ans *= plus.back();
          plus.pop_back();
        }
      } else if (2 <= plus.size()) {
        ans *= plus.back();
        plus.pop_back();
        ans *= plus.back();
        plus.pop_back();
      } else {
        ans *= minus.back();
        minus.pop_back();
        ans *= minus.back();
        minus.pop_back();
      }
    }
  } else {
    rep(i, k) {
      ans *= plus.back();
      plus.pop_back();
    }
  }

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

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<ll, int>;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;

const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream &operator>>(istream &is, mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
int main() {
  int n, k;
  cin >> n >> k;
  vector<ll> a(n);
  vector<ll> plus, minus;
  rep(i, n) {
    cin >> a[i];
    if (a[i] < 0)
      minus.push_back(a[i]);
    else
      plus.push_back(a[i]);
  }
  mint ans = 1;
  if (n == k) {
    rep(i, n) ans *= a[i];
    cout << ans << endl;
    return 0;
  }
  int ps = plus.size();
  int ms = minus.size();
  bool ok = false;
  if (k <= ps)
    ok = true; // 全てプラスから選べる場合
  else if (ps != 0)
    ok = true; // マイナスから選ばざるを得ないが,
               // プラスが一つ以上あればマイナスを偶数個選ぶことが出来る
  else if (k % 2 == 0)
    ok = true; // 全ての要素がマイナスだが, kが偶数のため答えはプラスにできる
  else
    ok =
        false; // プラスの数が0個で、kが奇数の場合はどうしても答えはマイナスになる

  if (!ok) {
    sort(a.begin(), a.end(), [](ll x, ll y) {
      return abs(x) < abs(y);
    }); // 絶対値の小さい順に並べる
    rep(i, k) { ans *= a[i]; }
    cout << ans << endl;
    return 0;
  }
  // 答えをプラスにできる場合はマイナスを偶数個選ばなければならない。
  sort(plus.begin(), plus.end());     // .backが最大値
  sort(minus.rbegin(), minus.rend()); // .backが最小値(絶対値で最大値)
  if (ps == 0) {
    // プラスが0個だった場合で答えが正になるのはマイナスが偶数個であるため、マイナスからすべて選んでOK.
    rep(i, k) {
      ans *= minus.back();
      minus.pop_back();
    }
  } else if (2 <= ms) {
    if (k % 2 == 1) {
      ans *= plus.back();
      plus.pop_back();
      k--;
    }
    rep(i, k / 2) {
      ll p = plus.back();
      p *= plus[plus.size() - 1];
      ll m = minus.back();
      m *= minus[minus.size() - 1];
      if (p < m) {
        ans *= minus.back();
        minus.pop_back();
        ans *= minus.back();
        minus.pop_back();
      } else {
        ans *= plus.back();
        plus.pop_back();
        ans *= plus.back();
        plus.pop_back();
      }
    }
  } else {
    rep(i, k) {
      ans *= plus.back();
      plus.pop_back();
    }
  }

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