Problem p02616 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
// #include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <ios>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
const ll MOD = 1000000007;

vector<ll> pos;
vector<ll> neg;
int zero = 0;

void solve(ll N, ll K, std::vector<ll> A) {
  REP(i, N) {
    if (A[i] > 0)
      pos.push_back(A[i]);
    else if (A[i] < 0)
      neg.push_back(A[i]);
    else
      zero++;
  }
  if ((N - zero > K && pos.size() > 0) ||
      (N - zero == K && neg.size() % 2 == 0) ||
      (pos.size() == 0 && K % 2 == 0)) {
    ll result = 1;
    ll must_pos = max(K - K / 2 * 2, K - (ll)neg.size() / 2 * 2);
    sort(pos.begin(), pos.end(), greater<ll>());
    sort(neg.begin(), neg.end());
    int pos_index = 0, neg_index = 0;
    for (; pos_index < must_pos; pos_index++) {
      result *= pos[pos_index];
      result %= MOD;
    }
    for (int i = (int)must_pos; i < K; i += 2) {
      if ((int)pos.size() >= pos_index + 2 &&
          (int)neg.size() >= neg_index + 2) {
        ll pp = pos[pos_index] * pos[pos_index + 1];
        ll nn = neg[neg_index] * neg[neg_index + 1];
        if (pp > nn) {
          pp %= MOD;
          result *= pp;
          result %= MOD;
          pos_index += 2;
        } else {
          nn %= MOD;
          result *= nn;
          result %= MOD;
          neg_index += 2;
        }
      } else if ((int)pos.size() >= pos_index + 2) {
        result *= pos[pos_index];
        result %= MOD;
        result *= pos[pos_index + 1];
        result %= MOD;
        pos_index += 2;
      } else {
        result *= neg[neg_index];
        result %= MOD;
        result *= neg[neg_index + 1];
        result %= MOD;
        neg_index += 2;
      }
    }
    cout << result << endl;
  } else if (zero) {
    cout << 0 << endl;
  } else {
    ll result = 1;
    sort(pos.begin(), pos.end());
    sort(neg.begin(), neg.end(), greater<ll>());
    auto p = pos.begin();
    auto n = neg.begin();
    REP(i, K) {
      if ((p == pos.end()) || (n != neg.end() && *p > -(*n))) {
        result *= -(*n);
        n++;
        result %= MOD;
      } else {
        result *= *p;
        p++;
        result %= MOD;
      }
    }
    cout << MOD - result << endl;
  }
}

int main() {
  ll N;
  (void)scanf("%lld", &N);
  ll K;
  (void)scanf("%lld", &K);
  std::vector<ll> A(N);
  for (int i = 0; i < N; i++) {
    (void)scanf("%lld", &A[i]);
  }
  solve(N, K, std::move(A));
  return 0;
}


Fixed submission:
#define _USE_MATH_DEFINES
// #include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <ios>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
const ll MOD = 1000000007;

vector<ll> pos;
vector<ll> neg;
int zero = 0;

void solve(ll N, ll K, std::vector<ll> A) {
  REP(i, N) {
    if (A[i] > 0)
      pos.push_back(A[i]);
    else if (A[i] < 0)
      neg.push_back(A[i]);
    else
      zero++;
  }
  if ((N - zero > K && pos.size() > 0) ||
      (N - zero > K && pos.size() == 0 && K % 2 == 0) ||
      (N - zero == K && neg.size() % 2 == 0)) {
    ll result = 1;
    ll must_pos = max(K - K / 2 * 2, K - (ll)neg.size() / 2 * 2);
    sort(pos.begin(), pos.end(), greater<ll>());
    sort(neg.begin(), neg.end());
    int pos_index = 0, neg_index = 0;
    for (; pos_index < must_pos; pos_index++) {
      result *= pos[pos_index];
      result %= MOD;
    }
    for (int i = (int)must_pos; i < K; i += 2) {
      if ((int)pos.size() >= pos_index + 2 &&
          (int)neg.size() >= neg_index + 2) {
        ll pp = pos[pos_index] * pos[pos_index + 1];
        ll nn = neg[neg_index] * neg[neg_index + 1];
        if (pp > nn) {
          pp %= MOD;
          result *= pp;
          result %= MOD;
          pos_index += 2;
        } else {
          nn %= MOD;
          result *= nn;
          result %= MOD;
          neg_index += 2;
        }
      } else if ((int)pos.size() >= pos_index + 2) {
        result *= pos[pos_index];
        result %= MOD;
        result *= pos[pos_index + 1];
        result %= MOD;
        pos_index += 2;
      } else {
        result *= neg[neg_index];
        result %= MOD;
        result *= neg[neg_index + 1];
        result %= MOD;
        neg_index += 2;
      }
    }
    cout << result << endl;
  } else if (zero) {
    cout << 0 << endl;
  } else {
    ll result = 1;
    sort(pos.begin(), pos.end());
    sort(neg.begin(), neg.end(), greater<ll>());
    auto p = pos.begin();
    auto n = neg.begin();
    REP(i, K) {
      if ((p == pos.end()) || (n != neg.end() && *p > -(*n))) {
        result *= -(*n);
        n++;
        result %= MOD;
      } else {
        result *= *p;
        p++;
        result %= MOD;
      }
    }
    cout << MOD - result << endl;
  }
}

int main() {
  ll N;
  (void)scanf("%lld", &N);
  ll K;
  (void)scanf("%lld", &K);
  std::vector<ll> A(N);
  for (int i = 0; i < N; i++) {
    (void)scanf("%lld", &A[i]);
  }
  solve(N, K, std::move(A));
  return 0;
}