Problem p02616 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
inline bool EQ(double a, double b) { return fabs(a - b) < 1e-9; }
inline int msbp(int x) { return 31 - __builtin_clz(x); }
inline int msb(int x) { return 1 << msbp(x); }
typedef long long ll;
typedef pair<int, int> pii;
// const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
// const int INF = INT_MAX;
// const int nINF = INT_MIN;
// const ll INF = LLONG_MAX;
// const ll nINF = LLONG_MIN;

/////////////////////////////////////////////////////////////////////

const int N = 2e5 + 10, M = 1e9 + 7;

ll mod(ll x) { return (x % M + M) % M; }
int add(ll a, ll b) { return mod(mod(a) + mod(b)); }
int mult(ll a, ll b) { return mod(mod(a) * mod(b)); }

int n, k, a[N], ans = 1;
vector<int> pos, neg;

signed main() {
  ios::sync_with_stdio(false);
  // cout << fixed << setprecision(7);
  cin >> n >> k;
  REP(i, n) cin >> a[i];
  REP(i, n) {
    if (a[i] > 0) {
      pos.push_back(a[i]);
    } else {
      neg.push_back(a[i]);
    }
  }
  if (pos.size()) {
    // we have a choice on number of positive numbers.
    if (k & 1) {
      // choose the biggest positive number first
      sort(pos.begin(), pos.end());
      ans = pos.back();
      pos.pop_back();
      --k;
    }
    vector<ll> all;
    sort(pos.begin(), pos.end(), greater<int>());
    sort(neg.begin(), neg.end());
    for (int i = 0; i + 1 < pos.size(); i += 2)
      all.push_back((ll)pos[i] * pos[i + 1]);
    for (int i = 0; i + 1 < neg.size(); i += 2)
      all.push_back((ll)neg[i] * neg[i + 1]);
    if ((pos.size() & 1) && (neg.size() & 1))
      all.push_back((ll)pos.back() * neg.back());
    sort(all.begin(), all.end(), greater<ll>());
    REP(i, k / 2) { ans = mult(ans, all[i]); }
    cout << ans << endl;
  } else {
    sort(neg.begin(), neg.end(), greater<int>());
    if (k & 1) {
      REP(i, k) ans = mult(ans, neg[i]);
    } else {
      FORD(i, neg.size() - 1, neg.size() - k) ans = mult(ans, neg[i]);
    }
    cout << ans << endl;
  }

  return 0;
}

// Easy things to check:
// - LONG LONGS (WA)
// - const int N is correct (WA, RTE) CHECK IF IT SHOULD BE 2*N!!!!
// - .size()-k underflow (WA, RTE, TLE)
// - small n edge cases (WA)

// Rare mistakes made in the past:
// - division by 0 (WA)
// - negative arithmetic, ceiling division, modulo (WA)
// - setprecision (WA)
// - INF not big enough using ll (WA)
// - setting max to 0 instead of -INF/min to 0 instead of INF (WA)
// - outputting debug (WA)
// - allocating too much memory (locRTE, MLE)
// - stack size (locRTE)
// - round announcements (WA)
// - multiset::erase (WA)
// - forgetting to rename recursive call when copy/pasting recursive function
// (WA)
// - not clearing DS between test cases EVEN FOR INPUT (WA, RTE, TLE, MLE)


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
inline bool EQ(double a, double b) { return fabs(a - b) < 1e-9; }
inline int msbp(int x) { return 31 - __builtin_clz(x); }
inline int msb(int x) { return 1 << msbp(x); }
typedef long long ll;
typedef pair<int, int> pii;
// const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
// const int INF = INT_MAX;
// const int nINF = INT_MIN;
// const ll INF = LLONG_MAX;
// const ll nINF = LLONG_MIN;

/////////////////////////////////////////////////////////////////////

const int N = 2e5 + 10, M = 1e9 + 7;

ll mod(ll x) { return (x % M + M) % M; }
int add(ll a, ll b) { return mod(mod(a) + mod(b)); }
int mult(ll a, ll b) { return mod(mod(a) * mod(b)); }

int n, k, a[N], ans = 1;
vector<int> pos, neg;

signed main() {
  ios::sync_with_stdio(false);
  // cout << fixed << setprecision(7);
  cin >> n >> k;
  REP(i, n) cin >> a[i];
  REP(i, n) {
    if (a[i] > 0) {
      pos.push_back(a[i]);
    } else {
      neg.push_back(a[i]);
    }
  }
  if (pos.size()) {
    // we have a choice on number of positive numbers.
    if (k & 1) {
      // choose the biggest positive number first
      sort(pos.begin(), pos.end());
      ans = pos.back();
      pos.pop_back();
      --k;
    }
    vector<ll> all;
    sort(pos.begin(), pos.end(), greater<int>());
    sort(neg.begin(), neg.end());
    for (int i = 0; i + 1 < pos.size(); i += 2)
      all.push_back((ll)pos[i] * pos[i + 1]);
    for (int i = 0; i + 1 < neg.size(); i += 2)
      all.push_back((ll)neg[i] * neg[i + 1]);
    if ((pos.size() & 1) && (neg.size() & 1))
      all.push_back((ll)pos.back() * neg.back());
    sort(all.begin(), all.end(), greater<ll>());
    REP(i, k / 2) { ans = mult(ans, all[i]); }
    cout << ans << endl;
  } else {
    sort(neg.begin(), neg.end());
    if (k & 1)
      reverse(neg.begin(), neg.end());
    REP(i, k) ans = mult(ans, neg[i]);
    cout << ans << endl;
  }

  return 0;
}

// Easy things to check:
// - LONG LONGS (WA)
// - const int N is correct (WA, RTE) CHECK IF IT SHOULD BE 2*N!!!!
// - .size()-k underflow (WA, RTE, TLE)
// - small n edge cases (WA)

// Rare mistakes made in the past:
// - division by 0 (WA)
// - negative arithmetic, ceiling division, modulo (WA)
// - setprecision (WA)
// - INF not big enough using ll (WA)
// - setting max to 0 instead of -INF/min to 0 instead of INF (WA)
// - outputting debug (WA)
// - allocating too much memory (locRTE, MLE)
// - stack size (locRTE)
// - round announcements (WA)
// - multiset::erase (WA)
// - forgetting to rename recursive call when copy/pasting recursive function
// (WA)
// - not clearing DS between test cases EVEN FOR INPUT (WA, RTE, TLE, MLE)