Problem p02616 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#define rep(i, m, n) for (int(i) = (int)(m); i < (int)(n); ++i)
#define rep2(i, m, n) for (int(i) = (int)(n)-1; i >= (int)(m); --i)
#define REP(i, n) rep(i, 0, n)
#define REP2(i, n) rep2(i, 0, n)
#define all(hoge) (hoge).begin(), (hoge).end()
#define en '\n'
using ll = long long;
using ull = unsigned long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
typedef pair<ll, ll> P;
constexpr long long INF = 1LL << 60;
constexpr int INF_INT = 1 << 25;
constexpr long long MOD = (ll)1e9 + 7;
// constexpr long long MOD = 998244353LL;
using ld = long double;
static const ld pi = 3.141592653589793L;
typedef vector<ll> Array;
typedef vector<Array> Matrix;

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

struct Edge {
  ll to, rev;
  long double cap;
  Edge(ll _to, long double _cap, ll _rev) {
    to = _to;
    cap = _cap;
    rev = _rev;
  }
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void add_edge(Graph &G, ll from, ll to, long double cap, bool revFlag,
              long double revCap) {
  G[from].push_back(Edge(to, cap, (ll)G[to].size()));
  if (revFlag)
    G[to].push_back(Edge(from, revCap, (ll)G[from].size() - 1));
}

template <int mod> struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while (n > 0) {
      if (n & 1)
        ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using mint = ModInt<MOD>;

void solve() {
  ll k, n;
  cin >> n >> k;
  vec<ll> a(n);
  REP(i, n) { cin >> a[i]; }

  if (k == n) {
    mint ans = 1;
    REP2(i, n) { ans *= a[i]; }
    cout << ans << en;
    return;
  }

  vec<ll> p, m;
  ll con0 = 0;
  REP(i, n) {
    if (a[i] > 0)
      p.push_back(a[i]);
    else if (a[i] < 0)
      m.push_back(a[i]);
    else
      con0++;
  }

  if (n - con0 < k or (con0 and ((k % 2 and n - con0 == m.size()) or
                                 (n - con0 == k and m.size() % 2)))) {
    cout << 0 << en;
    return;
  }

  sort(all(m));
  sort(all(p), greater<ll>());
  if (k % 2 and n == m.size()) {
    mint ans = 1;
    REP2(i, n) {
      if (k == 0)
        break;
      ans *= m[i];
      k--;
    }
    cout << ans << en;
    return;
  }

  vec<P> ms;
  mint ans = 1;
  for (int i = 0; i + 1 < n; i += 2) {
    if (k < 2)
      break;
    ms.push_back({m[i], m[i + 1]});
    ans *= m[i];
    ans *= m[i + 1];
    k -= 2;
  }

  for (int i = 0; i < k; i++) {
    ans *= p[i];
  }

  for (int i = k; i + 1 < p.size(); i += 2) {
    if (!ms.size())
      break;
    auto [m1, m2] = ms[ms.size() - 1];
    if (m1 * m2 < p[i] * p[i + 1]) {
      ans /= m1;
      ans /= m2;
      ms.pop_back();
      ans *= p[i];
      ans *= p[i + 1];
    } else {
      break;
    }
  }
  cout << ans << en;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  solve();
  /*
  ll t;
  cin >> t;
  REP(i, t)
  solve();
  */

  return 0;
}


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

#define rep(i, m, n) for (int(i) = (int)(m); i < (int)(n); ++i)
#define rep2(i, m, n) for (int(i) = (int)(n)-1; i >= (int)(m); --i)
#define REP(i, n) rep(i, 0, n)
#define REP2(i, n) rep2(i, 0, n)
#define all(hoge) (hoge).begin(), (hoge).end()
#define en '\n'
using ll = long long;
using ull = unsigned long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
typedef pair<ll, ll> P;
constexpr long long INF = 1LL << 60;
constexpr int INF_INT = 1 << 25;
constexpr long long MOD = (ll)1e9 + 7;
// constexpr long long MOD = 998244353LL;
using ld = long double;
static const ld pi = 3.141592653589793L;
typedef vector<ll> Array;
typedef vector<Array> Matrix;

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

struct Edge {
  ll to, rev;
  long double cap;
  Edge(ll _to, long double _cap, ll _rev) {
    to = _to;
    cap = _cap;
    rev = _rev;
  }
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void add_edge(Graph &G, ll from, ll to, long double cap, bool revFlag,
              long double revCap) {
  G[from].push_back(Edge(to, cap, (ll)G[to].size()));
  if (revFlag)
    G[to].push_back(Edge(from, revCap, (ll)G[from].size() - 1));
}

template <int mod> struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if ((x += p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if ((x += mod - p.x) >= mod)
      x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while (n > 0) {
      if (n & 1)
        ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using mint = ModInt<MOD>;

void solve() {
  ll k, n;
  cin >> n >> k;
  vec<ll> a(n);
  REP(i, n) { cin >> a[i]; }

  if (k == n) {
    mint ans = 1;
    REP2(i, n) { ans *= a[i]; }
    cout << ans << en;
    return;
  }

  vec<ll> p, m;
  ll con0 = 0;
  REP(i, n) {
    if (a[i] > 0)
      p.push_back(a[i]);
    else if (a[i] < 0)
      m.push_back(a[i]);
    else
      con0++;
  }

  if (n - con0 < k or (con0 and ((k % 2 and n - con0 == m.size()) or
                                 (n - con0 == k and m.size() % 2)))) {
    cout << 0 << en;
    return;
  }

  sort(all(m));
  sort(all(p), greater<ll>());
  if (k % 2 and n == m.size()) {
    mint ans = 1;
    REP2(i, n) {
      if (k == 0)
        break;
      ans *= m[i];
      k--;
    }
    cout << ans << en;
    return;
  }

  vec<P> ms;
  mint ans = 1;
  for (int i = 0; i + 1 < m.size(); i += 2) {
    if (k < 2)
      break;
    ms.push_back({m[i], m[i + 1]});
    ans *= m[i];
    ans *= m[i + 1];
    k -= 2;
  }

  for (int i = 0; i < k; i++) {
    ans *= p[i];
  }

  for (int i = k; i + 1 < p.size(); i += 2) {
    if (!ms.size())
      break;
    auto [m1, m2] = ms[ms.size() - 1];
    if (m1 * m2 < p[i] * p[i + 1]) {
      ans /= m1;
      ans /= m2;
      ms.pop_back();
      ans *= p[i];
      ans *= p[i + 1];
    } else {
      break;
    }
  }
  cout << ans << en;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  solve();
  /*
  ll t;
  cin >> t;
  REP(i, t)
  solve();
  */

  return 0;
}