Problem p02616 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdarg>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>

using namespace std;
#define INF 2e9 + 9
#define MOD 1000000007
#define ALL(v) v.begin(), v.end()
#define Int int64_t
#define pll pair<Int, Int>
template <class T> using pql = priority_queue<T, vector<T>>;
template <class T> using pq = priority_queue<T, vector<T>, greater<T>>;
#define ll(n)                                                                  \
  Int n;                                                                       \
  cin >> n;
#define LL(...)                                                                \
  Int __VA_ARGS___;                                                            \
  cin >> __VA_ARGS___;
#define OUT(...) cout << __VA_ARGS___;
#define RP(n, i, s) for (Int i = s; i < n; i++)
#define REP(n, i) for (Int i = 0; i < n; i++)
#define REPe(n, i) for (Int i = 1; i <= n; i++)
#define RPe(n, i, s) for (Int i = s; i <= n; i++)
#define upd_max(maxer, updater)                                                \
  if (maxer < updater)                                                         \
    maxer = updater;
#define upd_min(miner, updater)                                                \
  if (miner > updater)                                                         \
    miner = updater;
#ifdef DEBUG

#else

#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus < 201703L
#pragma GCC target("avx")
#else
#pragma GCC target("avx2")
#endif

#endif
// 実数の場合
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

void ansYes(bool flag) {
  if (flag)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}

void ansYES(bool flag) {
  if (flag)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}

struct node {
  Int to;
  Int length;
};

vector<Int> divisor(Int n) {
  vector<Int> ret;
  for (Int i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      ret.push_back(i);
      if (i * i != n)
        ret.push_back(n / i);
    }
  }
  return (ret);
}

int dx8[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};

int nanko(string s, Int n, Int i) {
  Int length = min(n - i - 1, i);
  Int ans = 0;
  for (int k = i - length; k < i; k++) {
    if (s.at(k) == 'R' && s.at(i + (i - k) == 'B'))
      ans++;
  }
  return ans;
}

struct datas {
  Int x;
};

// UnionFind群
/*
class UnionFind {
protected:
    vector<int> par;
    vector<int> data;
    int cnt;
public:
    UnionFind() : par(1), data(1), cnt(1) {};
    UnionFind(int N);
    int root(int x);
    int marge(int x, int y);
    bool same(int x, int y);
    int add();
    int add(int x);
    int solve();
    inline int getSize(int x) { return data.at(root(x)); };
};

UnionFind::UnionFind(int N) : par(N), data(N), cnt(N) {
    for (int i = 0; i < N; i++) {
        par.at(i) = -1;
        data.at(i) = 1;
    }
}


int UnionFind::root(int x) {
    if (par.at(x) == -1) return x;
    return par.at(x) = root(par.at(x)); // 経路圧縮
}

int UnionFind::marge(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) return rx;
    else { // ノード数の少ない方に接続
        if (data.at(rx) < data.at(ry)) swap(rx, ry);
        par.at(ry) = rx;
        data.at(rx) += data.at(ry);
        return rx;
    }
    return rx;
}

bool UnionFind::same(int x, int y) {
    return root(x) == root(y);
}

int UnionFind::add() {
    par.push_back(cnt);
    cnt++;
    return cnt - 1;
}

int UnionFind::add(int x) {
    par.push_back(cnt);
    cnt++;
    return marge(x, cnt);
}

int UnionFind::solve() {
    for (int i = 0; i < cnt;i++) {
        if (par.at(i) == -1) {

        }
    }
}*/

/*
int dfs(Int par, Int maxs, bool ans) {
    if (mita.at(par) == 1) return 0;
    if (maxs > h.at(par)) {
        maxs = h.at(par);
        ans = true;
    }else if (maxs == h.at(par)){
        ans = false;
    }

    Int maxer = 0;
    for (auto z : to[par]){
        mita.at(par) = 1;
        maxer = dfs(z,maxs,ans);
    }
}*/
int main() {
  Int n, k;
  cin >> n >> k;
  vector<Int> a(n);
  vector<Int> po;
  vector<Int> ne;
  Int zero = 0, plus = 0, minus = 0;
  REP(n, i) {
    cin >> a.at(i);
    if (a.at(i) < 0) {
      minus++;
      ne.push_back(a.at(i));
    }
    if (a.at(i) > 0) {
      plus++;
      po.push_back(a.at(i));
    }
    if (a.at(i) == 0) {
      zero++;
      po.push_back(a.at(i));
    }
  }
  sort(a.begin(), a.end());
  sort(po.begin(), po.end());
  sort(ne.begin(), ne.end(), greater<>());
  if (k == 1) {
    cout << a.at(n - 1) << endl;
    return 0;
  }
  bool flag = true;
  Int podex = zero + plus - 1;
  Int nedex = minus - 1;
  if (k == n && plus % 2 != k % 2)
    flag = false;
  if (plus == 0 && k % 2 == 1)
    flag = false;
  Int ans = 1;
  if (flag) {
    Int cnt = k - plus;
    cnt = cnt - cnt % 2;
    if (k % 2 == 1) {
      ans = ans * po.at(podex) % MOD;
      podex--;
      k--;
    }
    //      cout << cnt << endl;
    for (; k > 0;) {
      if (nedex < 1) {
        ans = ans * po.at(podex) % MOD;
        podex--;
        ans = ans * po.at(podex) % MOD;
        podex--;
        k -= 2;
        //        cout << "A" << endl;
      } else if (podex < 1) {
        ans = ans * (ne.at(nedex) * -1) % MOD;
        nedex--;
        ans = ans * (ne.at(nedex) * -1) % MOD;
        nedex--;
        cnt -= 2;
        k -= 2;
        //          cout << "B" << endl;
      } else {
        if (-ne.at(nedex) * -ne.at(nedex - 1) >
            po.at(podex) * po.at(podex - 1)) {
          ans = ans * (ne.at(nedex) * -1) % MOD;
          nedex--;
          ans = ans * (ne.at(nedex) * -1) % MOD;
          nedex--;
          cnt -= 2;
          k -= 2;
          //                    cout << "AA" << endl;
        } else {
          ans = ans * po.at(podex) % MOD;
          podex--;
          ans = ans * po.at(podex) % MOD;
          podex--;
          k -= 2;
          //   cout << "BB" << endl;
        }
      }
    }
    cout << ans << endl;
    return 0;
  } else {
    if (zero > 0) {
      cout << 0 << endl;
      return 0;
    }
    for (int i = 0; i < k; i++) {
      ans = ans * ne.at(i) % MOD;
    }
    if (ans < 0) {
      cout << ans + MOD << endl;
    } else {
      cout << ans << endl;
    }
  }
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdarg>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>

using namespace std;
#define INF 2e9 + 9
#define MOD 1000000007
#define ALL(v) v.begin(), v.end()
#define Int int64_t
#define pll pair<Int, Int>
template <class T> using pql = priority_queue<T, vector<T>>;
template <class T> using pq = priority_queue<T, vector<T>, greater<T>>;
#define ll(n)                                                                  \
  Int n;                                                                       \
  cin >> n;
#define LL(...)                                                                \
  Int __VA_ARGS___;                                                            \
  cin >> __VA_ARGS___;
#define OUT(...) cout << __VA_ARGS___;
#define RP(n, i, s) for (Int i = s; i < n; i++)
#define REP(n, i) for (Int i = 0; i < n; i++)
#define REPe(n, i) for (Int i = 1; i <= n; i++)
#define RPe(n, i, s) for (Int i = s; i <= n; i++)
#define upd_max(maxer, updater)                                                \
  if (maxer < updater)                                                         \
    maxer = updater;
#define upd_min(miner, updater)                                                \
  if (miner > updater)                                                         \
    miner = updater;
#ifdef DEBUG

#else

#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus < 201703L
#pragma GCC target("avx")
#else
#pragma GCC target("avx2")
#endif

#endif
// 実数の場合
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

void ansYes(bool flag) {
  if (flag)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}

void ansYES(bool flag) {
  if (flag)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}

struct node {
  Int to;
  Int length;
};

vector<Int> divisor(Int n) {
  vector<Int> ret;
  for (Int i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      ret.push_back(i);
      if (i * i != n)
        ret.push_back(n / i);
    }
  }
  return (ret);
}

int dx8[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};

int nanko(string s, Int n, Int i) {
  Int length = min(n - i - 1, i);
  Int ans = 0;
  for (int k = i - length; k < i; k++) {
    if (s.at(k) == 'R' && s.at(i + (i - k) == 'B'))
      ans++;
  }
  return ans;
}

struct datas {
  Int x;
};

// UnionFind群
/*
class UnionFind {
protected:
    vector<int> par;
    vector<int> data;
    int cnt;
public:
    UnionFind() : par(1), data(1), cnt(1) {};
    UnionFind(int N);
    int root(int x);
    int marge(int x, int y);
    bool same(int x, int y);
    int add();
    int add(int x);
    int solve();
    inline int getSize(int x) { return data.at(root(x)); };
};

UnionFind::UnionFind(int N) : par(N), data(N), cnt(N) {
    for (int i = 0; i < N; i++) {
        par.at(i) = -1;
        data.at(i) = 1;
    }
}


int UnionFind::root(int x) {
    if (par.at(x) == -1) return x;
    return par.at(x) = root(par.at(x)); // 経路圧縮
}

int UnionFind::marge(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) return rx;
    else { // ノード数の少ない方に接続
        if (data.at(rx) < data.at(ry)) swap(rx, ry);
        par.at(ry) = rx;
        data.at(rx) += data.at(ry);
        return rx;
    }
    return rx;
}

bool UnionFind::same(int x, int y) {
    return root(x) == root(y);
}

int UnionFind::add() {
    par.push_back(cnt);
    cnt++;
    return cnt - 1;
}

int UnionFind::add(int x) {
    par.push_back(cnt);
    cnt++;
    return marge(x, cnt);
}

int UnionFind::solve() {
    for (int i = 0; i < cnt;i++) {
        if (par.at(i) == -1) {

        }
    }
}*/

/*
int dfs(Int par, Int maxs, bool ans) {
    if (mita.at(par) == 1) return 0;
    if (maxs > h.at(par)) {
        maxs = h.at(par);
        ans = true;
    }else if (maxs == h.at(par)){
        ans = false;
    }

    Int maxer = 0;
    for (auto z : to[par]){
        mita.at(par) = 1;
        maxer = dfs(z,maxs,ans);
    }
}*/
int main() {
  Int n, k;
  cin >> n >> k;
  vector<Int> a(n);
  vector<Int> po;
  vector<Int> ne;
  Int zero = 0, plus = 0, minus = 0;
  REP(n, i) {
    cin >> a.at(i);
    if (a.at(i) < 0) {
      minus++;
      ne.push_back(a.at(i));
    }
    if (a.at(i) > 0) {
      plus++;
      po.push_back(a.at(i));
    }
    if (a.at(i) == 0) {
      zero++;
      po.push_back(a.at(i));
    }
  }
  sort(a.begin(), a.end());
  sort(po.begin(), po.end());
  sort(ne.begin(), ne.end(), greater<>());
  if (k == 1) {
    cout << a.at(n - 1) << endl;
    return 0;
  }
  bool flag = true;
  Int podex = zero + plus - 1;
  Int nedex = minus - 1;
  if (k == n && plus % 2 != k % 2)
    flag = false;
  if (plus == 0 && k % 2 == 1)
    flag = false;
  Int ans = 1;
  if (flag) {
    Int cnt = k - plus;
    cnt = cnt - cnt % 2;
    if (k % 2 == 1) {
      ans = ans * po.at(podex) % MOD;
      podex--;
      k--;
    }
    //      cout << cnt << endl;
    for (; k > 0;) {
      if (nedex < 1) {
        ans = ans * po.at(podex) % MOD;
        podex--;
        ans = ans * po.at(podex) % MOD;
        podex--;
        k -= 2;
        //        cout << "A" << endl;
      } else if (podex < 1) {
        ans = ans * (ne.at(nedex) * -1) % MOD;
        nedex--;
        ans = ans * (ne.at(nedex) * -1) % MOD;
        nedex--;
        cnt -= 2;
        k -= 2;
        //          cout << "B" << endl;
      } else {
        if (-ne.at(nedex) * -ne.at(nedex - 1) >
            po.at(podex) * po.at(podex - 1)) {
          ans = ans * (ne.at(nedex) * -1) % MOD;
          nedex--;
          ans = ans * (ne.at(nedex) * -1) % MOD;
          nedex--;
          cnt -= 2;
          k -= 2;
          //                    cout << "AA" << endl;
        } else {
          ans = ans * po.at(podex) % MOD;
          podex--;
          ans = ans * po.at(podex) % MOD;
          podex--;
          k -= 2;
          //   cout << "BB" << endl;
        }
      }
    }
    cout << ans << endl;
    return 0;
  } else {
    if (zero > 0) {
      cout << 0 << endl;
      return 0;
    }
    for (int i = 0; i < k; i++) {
      ans = ans * a.at(n - 1 - i) % MOD;
    }
    if (ans < 0) {
      cout << ans + MOD << endl;
    } else {
      cout << ans << endl;
    }
  }
}