Problem p02616 (C++)

Buggy submission (status: Runtime Error):
/*ver 5*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
void init() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
}
using ll = long long;
using ld = long double;
using vl = vector<ll>;
using vd = vector<ld>;
using vs = vector<string>;
using vb = vector<bool>;
using vvl = vector<vector<ll>>;
using vvd = vector<vector<ld>>;
using vvs = vector<vector<string>>;
using vvb = vector<vector<bool>>;
using pll = pair<ll, ll>;
using mll = map<ll, ll>;
#define EACH(x, v) for (auto &x : v)
#define FOR(i, a, b) for (ll i = (ll)a; i < (ll)b; i++)
#define REFOR(i, a, b) for (ll i = (ll)b - 1; i >= (ll)a; i--)
#define REP(i, n) for (ll i = 0; i < (ll)n; i++)
#define REREP(i, n) for (ll i = (ll)n - 1; i >= 0; i--)
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair
const ll INF = 1LL << 60;
#define CLR(mat, f) memset(mat, f, sizeof(mat))
#define IN(a, b, x) (a <= x && x <= b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end()) // 被り削除
#define debug cout << "line : " << __LINE__ << " debug" << endl;
#define ini(...)                                                               \
  int __VA_ARGS__;                                                             \
  in(__VA_ARGS__)
#define inl(...)                                                               \
  long long __VA_ARGS__;                                                       \
  in(__VA_ARGS__)
#define ind(...)                                                               \
  long double __VA_ARGS__;                                                     \
  in(__VA_ARGS__)
#define ins(...)                                                               \
  string __VA_ARGS__;                                                          \
  in(__VA_ARGS__)
#define inc(...)                                                               \
  char __VA_ARGS__;                                                            \
  in(__VA_ARGS__)
void in() {}
template <typename T, class... U> void in(T &t, U &...u) {
  cin >> t;
  in(u...);
}
void out() { cout << endl; }
template <typename T, class... U> void out(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u))
    cout << " ";
  out(u...);
}
template <typename T> void die(T x) {
  out(x);
  exit(0);
}
template <typename T> void in1(T &s) {
  REP(i, s.size()) { in(s[i]); }
}
template <typename T> void in2(T &s, T &t) {
  REP(i, s.size()) { in(s[i], t[i]); }
}
template <typename T> void in3(T &s, T &t, T &u) {
  REP(i, s.size()) { in(s[i], t[i], u[i]); }
}
template <typename T> void in4(T &s, T &t, T &u, T &v) {
  REP(i, s.size()) { in(s[i], t[i], u[i], v[i]); }
}
template <typename T> void in5(T &s, T &t, T &u, T &v, T &w) {
  REP(i, s.size()) { in(s[i], t[i], u[i], v[i], w[i]); }
}
template <typename T> void outv(T s) {
  REP(i, s.size()) { cout << s[i] << " "; }
  cout << endl;
}
template <typename T> void out1(T s) {
  REP(i, s.size()) { out(s[i]); }
}
template <typename T> void out2(T s, T t) {
  REP(i, s.size()) { out(s[i], t[i]); }
}
template <typename T> void out3(T s, T t, T u) {
  REP(i, s.size()) { out(s[i], t[i], u[i]); }
}
template <typename T> void out4(T s, T t, T u, T v) {
  REP(i, s.size()) { out(s[i], t[i], u[i], v[i]); }
}
template <typename T> void out5(T s, T t, T u, T v, T w) {
  REP(i, s.size()) { out(s[i], t[i], u[i], v[i], w[i]); }
}
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
template <typename T> T allSum(vector<T> a) {
  T ans = T();
  EACH(it, a) ans += it;
  return ans;
}
ll ceilDiv(ll a, ll b) { return (a + b - 1) / b; }
ld dist(pair<ld, ld> a, pair<ld, ld> b) {
  return sqrt(abs(a.fi - b.fi) * abs(a.fi - b.fi) +
              abs(a.se - b.se) * abs(a.se - b.se));
} // ２点間の距離
ll gcd(ll a, ll b) { return b != 0 ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
template <class A, class B> inline bool chmax(A &a, const B &b) {
  return b > a && (a = b, true);
}
template <class A, class B> inline bool chmin(A &a, const B &b) {
  return b < a && (a = b, true);
}
#define YES(n) ((n) ? "YES" : "NO")
#define Yes(n) ((n) ? "Yes" : "No")
#define yes(n) ((n) ? "yes" : "no")
const int mod = 1000000007;
class mint {
  long long x;

public:
  mint(long long 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 {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint &a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint &a) const {
    mint res(*this);
    return res *= 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 {
    mint res(*this);
    return res /= a;
  }
  friend ostream &operator<<(ostream &os, const mint &m) {
    os << m.x;
    return os;
  }
};
class UnionFind {
public:
  vector<ll> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
  vector<ll> siz; // siz[i]:iのサイズ　　(例) siz[3] = 2 : 3のサイズが2
  UnionFind(ll N) : par(N), siz(N, 1LL) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool unite(ll x, ll y) { // xとyの木を併合
    x = root(x);           // xの根をrx
    y = root(y);           // yの根をry
    if (x == y)
      return false; // xとyの根が同じ(=同じ木にある)時はそのまま
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] =
        x; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    return true;
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    return root(x) == root(y);
  }
  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};
class Dag {
public:
  vvl g;
  vl inCnt;
  vl sorted;
  bool sortedF = false;
  Dag(ll N) : g(N), inCnt(N) {}
  void input(ll x, ll y) {
    g[x].pb(y);
    inCnt[y]++;
  }
  bool tpSort() {
    vl tmp = inCnt;
    deque<ll> dq;
    vl ans;
    REP(i, g.size()) if (tmp[i] == 0) dq.pb(i);
    while (dq.size() != 0) {
      ll v = dq.front();
      dq.pop_front();
      ans.pb(v);
      EACH(it, g[v]) {
        tmp[it]--;
        if (tmp[it] == 0)
          dq.pb(it);
      }
    }
    sorted.swap(ans);
    sortedF = true;
    return sorted.size() == g.size();
  }
  ll longest() {
    if (sortedF == false)
      tpSort();
    vl dp(g.size(), 0);
    ll res = 0;
    EACH(it1, sorted) {
      EACH(it2, g[it1]) { chmax(dp[it2], dp[it1] + 1); }
      chmax(res, dp[it1]);
    }
    return res;
  }
};

bool com(ll a, ll b) {
  if (abs(a) < abs(b))
    return true;
  return false;
}
int main() {
  init();
  inl(N, K);
  vl p;
  p.reserve(N);
  vl m;
  m.reserve(N);
  bool z = false;
  REP(i, N) {
    inl(tmp);
    if (tmp > 0)
      p.pb(tmp);
    if (tmp < 0)
      m.pb(tmp);
    if (tmp == 0)
      z = true;
  }
  if (K % 2 == 1 && p.size() == 0) {
    if (z == true) {
      die(0);
    }
    sort(all(m), com);
    mint max = 1;
    REP(i, K) {
      if (i < m.size())
        max *= m[i];
      else
        max = 0;
    }
    die(max);
  }
  sort(rall(p), com);
  bool odd = false;
  ll other;
  if (K % 2 == 1) {
    odd = true;
    other = p.back();
    p.pop_back();
  }
  vl a;
  REP(i, p.size()) a.pb(p[i]);
  REP(i, m.size()) a.pb(m[i]);
  sort(all(a), com);
  mint max = 1;
  for (ll i = 0; i + 1 < K; i++) {
    if (*(a.end() - 1) ^ (*(a.end() - 2)) == false) {
      max *= *(a.end() - 1) ^ (*(a.end() - 2));
    }
  }
  if (odd == false) {
    die(max);
  } else {
    out(max * other);
  }
  return 0;
}

Fixed submission:
/*ver 5*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
void init() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
}
using ll = long long;
using ld = long double;
using vl = vector<ll>;
using vd = vector<ld>;
using vs = vector<string>;
using vb = vector<bool>;
using vvl = vector<vector<ll>>;
using vvd = vector<vector<ld>>;
using vvs = vector<vector<string>>;
using vvb = vector<vector<bool>>;
using pll = pair<ll, ll>;
using mll = map<ll, ll>;
#define EACH(x, v) for (auto &x : v)
#define FOR(i, a, b) for (ll i = (ll)a; i < (ll)b; i++)
#define REFOR(i, a, b) for (ll i = (ll)b - 1; i >= (ll)a; i--)
#define REP(i, n) for (ll i = 0; i < (ll)n; i++)
#define REREP(i, n) for (ll i = (ll)n - 1; i >= 0; i--)
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair
const ll INF = 1LL << 60;
#define CLR(mat, f) memset(mat, f, sizeof(mat))
#define IN(a, b, x) (a <= x && x <= b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end()) // 被り削除
#define debug cout << "line : " << __LINE__ << " debug" << endl;
#define ini(...)                                                               \
  int __VA_ARGS__;                                                             \
  in(__VA_ARGS__)
#define inl(...)                                                               \
  long long __VA_ARGS__;                                                       \
  in(__VA_ARGS__)
#define ind(...)                                                               \
  long double __VA_ARGS__;                                                     \
  in(__VA_ARGS__)
#define ins(...)                                                               \
  string __VA_ARGS__;                                                          \
  in(__VA_ARGS__)
#define inc(...)                                                               \
  char __VA_ARGS__;                                                            \
  in(__VA_ARGS__)
void in() {}
template <typename T, class... U> void in(T &t, U &...u) {
  cin >> t;
  in(u...);
}
void out() { cout << endl; }
template <typename T, class... U> void out(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u))
    cout << " ";
  out(u...);
}
template <typename T> void die(T x) {
  out(x);
  exit(0);
}
template <typename T> void in1(T &s) {
  REP(i, s.size()) { in(s[i]); }
}
template <typename T> void in2(T &s, T &t) {
  REP(i, s.size()) { in(s[i], t[i]); }
}
template <typename T> void in3(T &s, T &t, T &u) {
  REP(i, s.size()) { in(s[i], t[i], u[i]); }
}
template <typename T> void in4(T &s, T &t, T &u, T &v) {
  REP(i, s.size()) { in(s[i], t[i], u[i], v[i]); }
}
template <typename T> void in5(T &s, T &t, T &u, T &v, T &w) {
  REP(i, s.size()) { in(s[i], t[i], u[i], v[i], w[i]); }
}
template <typename T> void outv(T s) {
  REP(i, s.size()) { cout << s[i] << " "; }
  cout << endl;
}
template <typename T> void out1(T s) {
  REP(i, s.size()) { out(s[i]); }
}
template <typename T> void out2(T s, T t) {
  REP(i, s.size()) { out(s[i], t[i]); }
}
template <typename T> void out3(T s, T t, T u) {
  REP(i, s.size()) { out(s[i], t[i], u[i]); }
}
template <typename T> void out4(T s, T t, T u, T v) {
  REP(i, s.size()) { out(s[i], t[i], u[i], v[i]); }
}
template <typename T> void out5(T s, T t, T u, T v, T w) {
  REP(i, s.size()) { out(s[i], t[i], u[i], v[i], w[i]); }
}
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
template <typename T> T allSum(vector<T> a) {
  T ans = T();
  EACH(it, a) ans += it;
  return ans;
}
ll ceilDiv(ll a, ll b) { return (a + b - 1) / b; }
ld dist(pair<ld, ld> a, pair<ld, ld> b) {
  return sqrt(abs(a.fi - b.fi) * abs(a.fi - b.fi) +
              abs(a.se - b.se) * abs(a.se - b.se));
} // ２点間の距離
ll gcd(ll a, ll b) { return b != 0 ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
template <class A, class B> inline bool chmax(A &a, const B &b) {
  return b > a && (a = b, true);
}
template <class A, class B> inline bool chmin(A &a, const B &b) {
  return b < a && (a = b, true);
}
#define YES(n) ((n) ? "YES" : "NO")
#define Yes(n) ((n) ? "Yes" : "No")
#define yes(n) ((n) ? "yes" : "no")
const int mod = 1000000007;
class mint {
  long long x;

public:
  mint(long long 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 {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint &a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint &a) const {
    mint res(*this);
    return res *= 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 {
    mint res(*this);
    return res /= a;
  }
  friend ostream &operator<<(ostream &os, const mint &m) {
    os << m.x;
    return os;
  }
};
class UnionFind {
public:
  vector<ll> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
  vector<ll> siz; // siz[i]:iのサイズ　　(例) siz[3] = 2 : 3のサイズが2
  UnionFind(ll N) : par(N), siz(N, 1LL) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }
  ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool unite(ll x, ll y) { // xとyの木を併合
    x = root(x);           // xの根をrx
    y = root(y);           // yの根をry
    if (x == y)
      return false; // xとyの根が同じ(=同じ木にある)時はそのまま
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] =
        x; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    return true;
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    return root(x) == root(y);
  }
  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};
class Dag {
public:
  vvl g;
  vl inCnt;
  vl sorted;
  bool sortedF = false;
  Dag(ll N) : g(N), inCnt(N) {}
  void input(ll x, ll y) {
    g[x].pb(y);
    inCnt[y]++;
  }
  bool tpSort() {
    vl tmp = inCnt;
    deque<ll> dq;
    vl ans;
    REP(i, g.size()) if (tmp[i] == 0) dq.pb(i);
    while (dq.size() != 0) {
      ll v = dq.front();
      dq.pop_front();
      ans.pb(v);
      EACH(it, g[v]) {
        tmp[it]--;
        if (tmp[it] == 0)
          dq.pb(it);
      }
    }
    sorted.swap(ans);
    sortedF = true;
    return sorted.size() == g.size();
  }
  ll longest() {
    if (sortedF == false)
      tpSort();
    vl dp(g.size(), 0);
    ll res = 0;
    EACH(it1, sorted) {
      EACH(it2, g[it1]) { chmax(dp[it2], dp[it1] + 1); }
      chmax(res, dp[it1]);
    }
    return res;
  }
};

bool com(ll a, ll b) {
  if (abs(a) < abs(b))
    return true;
  return false;
}
int main() {
  init();
  inl(N, K);
  vl a(N);
  in1(a);
  sort(rall(a), com);
  mint Max = 1;
  bool pls = true;
  bool zr = false;
  REP(i, K) {
    Max *= a[i];
    pls ^= (a[i] < 0);
    zr |= (a[i] == 0);
  }
  if (pls || zr)
    die(Max);
  // max!=0
  ll inP = INF, outP = INF, inM = INF, outM = INF;
  REREP(i, K) {
    if (inP == INF && a[i] > 0)
      inP = a[i];
    if (inM == INF && a[i] < 0)
      inM = a[i];
  }
  FOR(i, K, N) {
    if (outP == INF && a[i] >= 0)
      outP = a[i];
    if (outM == INF && a[i] < 0)
      outM = a[i];
  }
  if (inP != INF && outP != INF && inM != INF && outM != INF) {
    // outM/inP or outP/inM
    // outM*inM or outP*inP
    if (outM * inM < outP * inP)
      Max *= (mint)outP / inM;
    else
      Max *= (mint)outM / inP;
    die(Max);
  }
  if (inP != INF && outM != INF) {
    Max *= (mint)outM / inP;
    die(Max);
  }
  if (inM != INF && outP != INF) {
    Max *= (mint)outP / inM;
    die(Max);
  }
  Max = 1;
  REP(i, K) { Max *= a[N - 1 - i]; }
  out(Max);
  return 0;
}