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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
const int INF = 1000000000;
const int MOD = 1000000007;
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  int neg = 0;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    if (a[i] < 0)
      neg++;
  }
  // 0以上を作れるかそうでないか.
  // 非負に出来る->負から偶数個選ぶような場合が存在する.

  bool flag = false;
  for (int i = 0; i <= min(neg, k); i += 2) {
    if (k - i <= n - neg) {
      flag = true;
    }
  }

  if (flag == false) {
    sort(a.begin(), a.end(),
         [](int i, int j) -> bool { return abs(i) < abs(j); });

    ll ans = 1;
    for (int i = 0; i < k; i++) {
      if (a[i] < 0) {
        ans *= (MOD + a[i]);
      } else
        ans *= a[i];

      ans %= MOD;
    }
    cout << ans << endl;
  } else {
    // 最大限正の数から取って,うしろ2つの積を比較.
    vector<ll> narr;
    vector<ll> parr;
    for (int i = 0; i < n; i++) {
      if (a[i] < 0)
        narr.push_back(a[i]);
      else
        parr.push_back(a[i]);
    }

    int p = parr.size();
    int q = narr.size();

    sort(parr.begin(), parr.end(), greater<ll>());
    sort(narr.begin(), narr.end());

    int neg_num;
    for (int i = 0; i <= min(q, k); i += 2)
      neg_num = i;             // negを取る個数
    int pos_num = k - neg_num; // posを取る個数

    while (neg_num && pos_num < p) {
      // neg_numを2ずつ減らしてpos_numを2ずつ増やすとき,
      if (narr[neg_num - 1] * narr[neg_num - 2] >=
          parr[pos_num] * parr[pos_num + 1])
        break;
      neg_num -= 2;
      pos_num += 2;
    }

    ll ans = 1;
    for (int i = 0; i < neg_num; i++) {
      ans *= (MOD + narr[i]);
      ans %= MOD;
    }
    for (int i = 0; i < pos_num; i++) {
      ans *= parr[i];
      ans %= MOD;
    }

    cout << ans << endl;
  }
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;
const int INF = 1000000000;
const int MOD = 1000000007;
int main() {
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  int neg = 0;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    if (a[i] < 0)
      neg++;
  }
  // 0以上を作れるかそうでないか.
  // 非負に出来る->負から偶数個選ぶような場合が存在する.

  bool flag = false;
  for (int i = 0; i <= neg; i += 2) {
    if (i + (n - neg) == k)
      flag = true;
  }

  if (flag == false) {
    vector<ll> arr(n);
    for (int i = 0; i < n; i++)
      arr[i] = abs(a[i]);

    sort(arr.begin(), arr.end());
    ll ans = 1;
    for (int i = 0; i < k; i++) {
      ans *= arr[i];
      ans %= MOD;
    }

    cout << MOD - ans << endl;
  } else {
    // 最大限正の数から取って,うしろ2つの積を比較.
    vector<ll> narr;
    vector<ll> parr;
    for (int i = 0; i < n; i++) {
      if (a[i] < 0)
        narr.push_back(a[i]);
      else
        parr.push_back(a[i]);
    }

    int p = parr.size();
    int q = narr.size();

    sort(parr.begin(), parr.end(), greater<ll>());
    sort(narr.begin(), narr.end());

    int neg_num;
    for (int i = 0; i <= q; i += 2)
      neg_num = i;             // negを取る個数
    int pos_num = k - neg_num; // posを取る個数

    while (neg_num && pos_num != p) {
      // neg_numを2ずつ減らしてpos_numを2ずつ増やすとき,
      if (narr[neg_num - 1] * narr[neg_num - 2] >=
          parr[pos_num] * parr[pos_num + 1])
        break;
      neg_num -= 2;
      pos_num += 2;
    }

    ll ans = 1;
    for (int i = 0; i < neg_num; i++) {
      ans *= abs(narr[i]);
      ans %= MOD;
    }
    for (int i = 0; i < pos_num; i++) {
      ans *= parr[i];
      ans %= MOD;
    }

    cout << ans << endl;
  }
}