Problem p02616 (C++)

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

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto &e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
// srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())

ll MOD(ll x, ll m) {
  ll r = x % m;
  if (r < 0) {
    r += m;
  }
  return r;
}

ostream &operator<<(ostream &str, const pll &p) {
  str << p.first << " " << p.second;
  return str;
}

template <typename T> void join(T &arr, string sep) {
  bool first = true;
  for (auto t : arr) {
    if (first) {
      first = false;
      cout << t;
    } else {
      cout << sep << t;
    }
  }
  cout << "\n";
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 9e18
#define MINF -INF

const ll md = 1e9 + 7;

void add_self(ll &a, ll b) { a = MOD((a + b), md); }

void sub_self(ll &a, ll b) { a = MOD((a - b), md); }

void mul_self(ll &a, ll b) { a = MOD((a * MOD(b, md)), md); }

void solve() {
  ll n, k;
  cin >> n >> k;
  vll a(n);
  vll pos;
  vll neg;
  vll zeros;
  REP(i, n) {
    cin >> a[i];
    if (a[i] > 0) {
      pos.push_back(a[i]);
    } else if (a[i] < 0) {
      neg.push_back(a[i]);
    } else {
      zeros.push_back(a[i]);
    }
  }
  ll negSize = neg.size();
  ll posSize = pos.size();
  if (k > posSize + negSize) {
    cout << "0\n";
    return;
  }

  SORTREV(pos);
  SORT(neg);
  if (k > posSize && (((k - posSize) % 2) == 1)) {
    if (!pos.empty()) {
      pos.pop_back();
      posSize--;
    } else {
      if (!zeros.empty()) {
        cout << "0\n";
        return;
      }
      ll res = 1;
      REP(i, k) { mul_self(res, neg.end()[-(i + 1)]); }
      cout << res << "\n";
      return;
    }
  }
  vll posNeg;

  for (ll i = 0; i < negSize - 1; i += 2) {
    posNeg.push_back(neg[i] * neg[i + 1]);
  }
  ll posNegSize = posNeg.size();
  ll res = 1;
  ll i = 0;
  ll j = 0;
  while (k > 0) {
    if (k == 1) {
      assert(i < posSize);
      mul_self(res, pos[i++]);
      k--;
      continue;
    }
    if (j >= posNegSize) {
      assert(i < posSize);
      mul_self(res, pos[i++]);
      k--;
      continue;
    }
    if (i >= posSize) {
      assert(j < posNegSize);
      mul_self(res, posNeg[j++]);
      k -= 2;
      continue;
    }
    if (i < posSize - 1) {
      ll t = pos[i] * pos[i + 1];
      if (t < posNeg[j]) {
        mul_self(res, posNeg[j++]);
        k -= 2;
        continue;
      }
      mul_self(res, t);
      k -= 2;
      i += 2;
      continue;
    }
    if (pos[i] < posNeg[j]) {
      mul_self(res, posNeg[j++]);
      k -= 2;
      continue;
    }
    mul_self(res, a[i++]);
    k--;
  }
  assert(k == 0);

  // cout << fixed << setprecision(6);
  cout << res << "\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int tt = 1;
  // cin >> tt;
  for (int t = 1; t <= tt; t++) {
    // cout << "Case #" << t << ": ";
    solve();
  }
  // cin.rdbuf()->in_avail()
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto &e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
// srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())

ll MOD(ll x, ll m) {
  ll r = x % m;
  if (r < 0) {
    r += m;
  }
  return r;
}

ostream &operator<<(ostream &str, const pll &p) {
  str << p.first << " " << p.second;
  return str;
}

template <typename T> void join(T &arr, string sep) {
  bool first = true;
  for (auto t : arr) {
    if (first) {
      first = false;
      cout << t;
    } else {
      cout << sep << t;
    }
  }
  cout << "\n";
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 9e18
#define MINF -INF

const ll md = 1e9 + 7;

void add_self(ll &a, ll b) { a = MOD((a + b), md); }

void sub_self(ll &a, ll b) { a = MOD((a - b), md); }

void mul_self(ll &a, ll b) { a = MOD((a * MOD(b, md)), md); }

void solve() {
  ll n, k;
  cin >> n >> k;
  vll a(n);
  vll pos;
  vll neg;
  vll zeros;
  REP(i, n) {
    cin >> a[i];
    if (a[i] > 0) {
      pos.push_back(a[i]);
    } else if (a[i] < 0) {
      neg.push_back(a[i]);
    } else {
      zeros.push_back(a[i]);
    }
  }
  ll negSize = neg.size();
  ll posSize = pos.size();
  if (k > posSize + negSize) {
    cout << "0\n";
    return;
  }

  if (k == n) {
    ll res = 1;
    REP(i, n) { mul_self(res, a[i]); }
    cout << res << "\n";
    return;
  }

  if (k == posSize + negSize) {
    if (negSize % 2 == 1) {
      cout << "0\n";
      return;
    }
    ll res = 1;
    REP(i, posSize) { mul_self(res, pos[i]); }
    REP(i, negSize) { mul_self(res, neg[i]); }
    cout << res << "\n";
    return;
  }

  SORTREV(pos);
  SORT(neg);
  if (k > posSize && (((k - posSize) % 2) == 1)) {
    if (!pos.empty()) {
      pos.pop_back();
      posSize--;
    } else {
      if (!zeros.empty()) {
        cout << "0\n";
        return;
      }
      ll res = 1;
      REP(i, k) { mul_self(res, neg.end()[-(i + 1)]); }
      cout << res << "\n";
      return;
    }
  }
  vll posNeg;

  for (ll i = 0; i < negSize - 1; i += 2) {
    posNeg.push_back(neg[i] * neg[i + 1]);
  }
  ll posNegSize = posNeg.size();
  ll res = 1;
  ll i = 0;
  ll j = 0;
  while (k > 0) {
    if (k == 1) {
      assert(i < posSize);
      mul_self(res, pos[i++]);
      k--;
      continue;
    }
    if (j >= posNegSize) {
      assert(i < posSize);
      mul_self(res, pos[i++]);
      k--;
      continue;
    }
    if (i >= posSize) {
      assert(j < posNegSize);
      mul_self(res, posNeg[j++]);
      k -= 2;
      continue;
    }
    if (i < posSize - 1) {
      ll t = pos[i] * pos[i + 1];
      if (t < posNeg[j]) {
        mul_self(res, posNeg[j++]);
        k -= 2;
        continue;
      }
      mul_self(res, t);
      k -= 2;
      i += 2;
      continue;
    }
    if (pos[i] < posNeg[j]) {
      mul_self(res, posNeg[j++]);
      k -= 2;
      continue;
    }
    mul_self(res, a[i++]);
    k--;
  }
  assert(k == 0);

  // cout << fixed << setprecision(6);
  cout << res << "\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int tt = 1;
  // cin >> tt;
  for (int t = 1; t <= tt; t++) {
    // cout << "Case #" << t << ": ";
    solve();
  }
  // cin.rdbuf()->in_avail()
  return 0;
}