Problem p02616 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
using ll = long long;
using P = pair<int, int>;
ll mod = 1e9 + 7;

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  vector<int> pos, neg;
  rep(i, n) {
    cin >> a.at(i);
    if (a.at(i) < 0)
      neg.push_back(a.at(i));
    else
      pos.push_back(a.at(i));
  }

  int posSize = pos.size();
  int negSize = neg.size();
  bool ok = false; // 選び方によって、答えを正にすることができる場合 true
  if (posSize > 0) {
    if (n == k)
      ok = (negSize % 2 == 0);
    else
      ok = true;
  } else {
    ok = (k % 2 == 0);
  }

  ll ans = 1;
  if (!ok) {
    sort(a.begin(), a.end(), [](int x, int y) { return abs(x) < abs(y); });
    rep(i, k) ans = ans * a.at(i) % mod;
    ans = mod + ans;
  } else {
    sort(pos.begin(), pos.end());
    sort(neg.rbegin(), neg.rend());
    if (k % 2 == 1) {
      ans = ans * pos.back() % mod;
      pos.pop_back();
    }

    vector<ll> p;
    while (pos.size() >= 2) {
      ll x = pos.back();
      pos.pop_back();
      x *= pos.back();
      pos.pop_back();
      p.push_back(x);
    }
    while (neg.size() >= 2) {
      ll x = neg.back();
      neg.pop_back();
      x *= neg.back();
      neg.pop_back();
      p.push_back(x);
    }
    sort(p.rbegin(), p.rend());
    rep(i, k / 2) ans = ans * (p.at(i) % mod) % mod;
  }

  cout << ans << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
using ll = long long;
using P = pair<int, int>;
ll mod = 1e9 + 7;

bool compare(pair<ll, bool> a, pair<ll, bool> b) { return a.first > b.first; }

int main() {
  int n, k;
  cin >> n >> k;
  vector<pair<ll, bool>> a;
  bool isAllNegative = true; // すべて負の場合true
  rep(i, n) {
    int x;
    cin >> x;
    if (x >= 0) {
      a.emplace_back(x, true);
      isAllNegative = false;
    } else {
      a.emplace_back(-x, false);
    }
  }

  sort(a.begin(), a.end(), compare); // 絶対値の大きい順にする

  ll ans = 1;
  // ケース1: すべて負の場合
  if (isAllNegative) {
    for (int i = n - 1; i >= n - k; i--) {
      ans = ans * a.at(i).first % mod;
    }
    cout << mod - ans << endl;
    return 0;
  }

  bool isPositive = true;
  int lastPositive = -1;
  int lastNegative = -1;
  for (int i = 0; i < k; i++) {
    isPositive = (isPositive == a.at(i).second);
    if (a.at(i).second)
      lastPositive = i;
    else
      lastNegative = i;
  }

  // ケース2: 絶対値の大きい順にk個取って、正になる場合
  if (isPositive) {
    for (int i = 0; i < k; i++) {
      ans = ans * a.at(i).first % mod;
    }
    cout << ans << endl;
    return 0;
  }

  // ケース3: 絶対値の大きい順にk個取って、負になる場合
  int nextPositive = -1;
  int nextNegative = -1;
  for (int i = 0; i < k; i++) {
    if (a.at(i).second) {
      if (nextPositive != -1)
        continue;
      nextPositive = i;
    } else {
      if (nextNegative != -1)
        continue;
      nextNegative = i;
    }
    if (nextPositive != -1 && nextNegative != -1)
      break;
  }

  if (lastPositive == -1 || nextNegative == -1 ||
      (lastNegative != -1 && nextPositive != 1 &&
       a.at(lastPositive).first * a.at(nextPositive).first >=
           a.at(lastNegative).first * a.at(nextNegative).first)) {
    for (int i = 0; i < k; i++) {
      if (i == lastNegative) {
        ans = ans * (a.at(nextPositive).first % mod) % mod;
      } else {
        ans = ans * a.at(i).first % mod;
      }
    }
  } else {
    for (int i = 0; i < k; i++) {
      if (i == lastPositive) {
        ans = ans * (a.at(nextNegative).first % mod) % mod;
      } else {
        ans = ans * (a.at(i).first % mod) % mod;
      }
    }
  }

  cout << ans << endl;
  return 0;
}