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

// 競技プログラミング用のテンプレート
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)

using namespace std;
// エイリアス
using ll = long long int;
using p = pair<int, int>;
using pl = pair<ll, ll>;
using v = vector<int>;
using vd = vector<double>;
using vs = vector<string>;
using vl = vector<ll>;

// 定数
const int intmax = numeric_limits<int>::max();
const ll llmax = numeric_limits<ll>::max();
const ll llmin = numeric_limits<ll>::min();
const ll mod = 1e9 + 7;
const double pi = M_PI;

ll calc_only(vl &src, int k) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    ans *= src[i];
    ans %= mod;
  }
  return ans;
}

ll calc_mix_even(vector<pair<ll, int>> &mix, int k) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    ans *= mix[i].first;
    ans %= mod;
  }
  return ans;
}

ll calc_mix_odd_without(vector<pair<ll, int>> &mix, int k, int target) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    if (i == target)
      continue;
    ans *= mix[i].first;
    ans %= mod;
  }
  return ans;
}

int get_last_index(vector<pair<ll, int>> &mix, int k, int target) {
  int last_index = -1;
  for (int i = 0; i < k; i++) {
    if (mix[i].second == target)
      last_index = i;
  }
  return last_index;
}

int get_first_index(vector<pair<ll, int>> &mix, int k, int target) {
  for (int i = k; i < mix.size(); i++) {
    if (mix[i].second == target)
      return i;
  }
  return -1;
}

ll adapt(vector<pair<ll, int>> &mix, int k, int without, int add) {
  ll ans = calc_mix_odd_without(mix, k, without);
  ans *= mix[add].first;
  ans %= mod;
  return ans;
}

ll calc_mix_odd(vector<pair<ll, int>> &mix, int k) {
  ll ans = llmin;
  int plus_last = get_last_index(mix, k, 1);
  int minus_last = get_last_index(mix, k, -1);
  int plus_first = get_first_index(mix, k, 1);
  int minus_first = get_first_index(mix, k, -1);
  if (plus_last == -1) {
    // プラスが<kにそもそも存在しない
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
  if (plus_first == -1) {
    // プラスが>=kに存在しない
    // プラスを取り除いてマイナスを入れる
    return adapt(mix, k, plus_last, minus_first);
  }
  if (minus_first == -1) {
    // マイナスが>=kに存在しない
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
  ll plus1 = mix[plus_last].first;
  ll minus1 = mix[minus_last].first;
  ll plus2 = mix[plus_first].first;
  ll minus2 = mix[minus_first].first;
  if (plus1 * plus2 < minus1 * minus2) {
    // プラスを取り除いてマイナスを入れる
    return adapt(mix, k, plus_last, minus_first);
  } else {
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
}

ll calc_mix(vector<pair<ll, int>> &mix, int k) {
  int num_minus_in_k = 0;
  for (int i = 0; i < k; i++) {
    if (mix[i].second == -1)
      num_minus_in_k++;
  }
  if (num_minus_in_k % 2 == 0) {
    return calc_mix_even(mix, k);
  }
  if (num_minus_in_k % 2 != 0) {
    return calc_mix_odd(mix, k);
  }
}

int main() {
  int n, k;
  cin >> n >> k;
  vl as(n, 0);
  vl plus, minus, minusr;
  vector<pair<ll, int>> abss(n);
  rep(i, n) {
    ll a;
    cin >> a;
    as[i] = a;
    if (a < 0) {
      minus.push_back(a);
      abss[i] = {abs(a), -1};
    } else {
      plus.push_back(a);
      abss[i] = {a, 1};
    }
  }
  sort(plus.begin(), plus.end());
  reverse(plus.begin(), plus.end());
  sort(minus.begin(), minus.end());
  minusr = minus;
  reverse(minusr.begin(), minusr.end());
  sort(abss.begin(), abss.end());
  reverse(abss.begin(), abss.end());
  // 全部正
  if (plus.size() == n) {
    ll ans = calc_only(plus, k);
    cout << ans << endl;
    return 0;
  }
  // 全部負
  if (minus.size() == n) {
    ll ans = llmin;
    if (k % 2 == 0)
      ans = calc_only(minus, k);
    if (k % 2 != 0)
      ans = calc_only(minusr, k);
    if (ans < 0)
      ans += mod;
    cout << ans << endl;
    return 0;
  }
  // n == k
  if (n == k) {
    ll ans = calc_only(as, k);
    if (ans < 0)
      ans += mod;
    cout << ans << endl;
    return 0;
  }
  // それ以外
  ll ans = calc_mix(abss, k);
  cout << ans << endl;
}


Error: 0

Fixed submission:

// 競技プログラミング用のテンプレート
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)

using namespace std;
// エイリアス
using ll = long long int;
using p = pair<int, int>;
using pl = pair<ll, ll>;
using v = vector<int>;
using vd = vector<double>;
using vs = vector<string>;
using vl = vector<ll>;

// 定数
const int intmax = numeric_limits<int>::max();
const ll llmax = numeric_limits<ll>::max();
const ll llmin = numeric_limits<ll>::min();
const ll mod = 1e9 + 7;
const double pi = M_PI;

ll calc_only(vl &src, int k) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    ans *= src[i];
    ans %= mod;
  }
  return ans;
}

ll calc_mix_even(vector<pair<ll, int>> &mix, int k) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    ans *= mix[i].first;
    ans %= mod;
  }
  return ans;
}

ll calc_mix_odd_without(vector<pair<ll, int>> &mix, int k, int target) {
  ll ans = 1;
  for (int i = 0; i < k; i++) {
    if (i == target)
      continue;
    ans *= mix[i].first;
    ans %= mod;
  }
  return ans;
}

int get_last_index(vector<pair<ll, int>> &mix, int k, int target) {
  int last_index = -1;
  for (int i = 0; i < k; i++) {
    if (mix[i].second == target)
      last_index = i;
  }
  return last_index;
}

int get_first_index(vector<pair<ll, int>> &mix, int k, int target) {
  int last_index = -1;
  for (int i = k; i < mix.size(); i++) {
    if (mix[i].second == target)
      return i;
  }
}

ll adapt(vector<pair<ll, int>> &mix, int k, int without, int add) {
  ll ans = calc_mix_odd_without(mix, k, without);
  ans *= mix[add].first;
  ans %= mod;
  return ans;
}

ll calc_mix_odd(vector<pair<ll, int>> &mix, int k) {
  ll ans = llmin;
  int plus_last = get_last_index(mix, k, 1);
  int minus_last = get_last_index(mix, k, -1);
  int plus_first = get_first_index(mix, k, 1);
  int minus_first = get_first_index(mix, k, -1);
  if (plus_last == -1) {
    // プラスが<kにそもそも存在しない
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
  if (plus_first == -1) {
    // プラスが>=kに存在しない
    // プラスを取り除いてマイナスを入れる
    return adapt(mix, k, plus_last, minus_first);
  }
  if (minus_first == -1) {
    // マイナスが>=kに存在しない
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
  ll plus1 = mix[plus_last].first;
  ll minus1 = mix[minus_last].first;
  ll plus2 = mix[plus_first].first;
  ll minus2 = mix[minus_first].first;
  if (minus_last == -1)
    return 0;
  if (plus1 * plus2 < minus1 * minus2) {
    // プラスを取り除いてマイナスを入れる
    return adapt(mix, k, plus_last, minus_first);
  } else {
    // マイナスを取り除いてプラスを入れる
    return adapt(mix, k, minus_last, plus_first);
  }
}

ll calc_mix(vector<pair<ll, int>> mix, int k) {
  int num_minus_in_k = 0;
  for (int i = 0; i < k; i++) {
    if (mix[i].second == -1)
      num_minus_in_k++;
  }
  if (num_minus_in_k % 2 == 0) {
    return calc_mix_even(mix, k);
  }
  if (num_minus_in_k % 2 != 0) {
    return calc_mix_odd(mix, k);
  }
}

int main() {
  int n, k;
  cin >> n >> k;
  vl as(n, 0);
  vl plus, minus, minusr;
  vector<pair<ll, int>> abss(n);
  rep(i, n) {
    ll a;
    cin >> a;
    as[i] = a;
    if (a < 0) {
      minus.push_back(a);
      abss[i] = {abs(a), -1};
    } else {
      plus.push_back(a);
      abss[i] = {a, 1};
    }
  }
  sort(plus.begin(), plus.end());
  reverse(plus.begin(), plus.end());
  sort(minus.begin(), minus.end());
  minusr = minus;
  reverse(minusr.begin(), minusr.end());
  sort(abss.begin(), abss.end());
  reverse(abss.begin(), abss.end());
  // 全部正
  if (plus.size() == n) {
    ll ans = calc_only(plus, k);
    cout << ans << endl;
    return 0;
  }
  // 全部負
  if (minus.size() == n) {
    ll ans = llmin;
    if (k % 2 == 0)
      ans = calc_only(minus, k);
    if (k % 2 != 0)
      ans = calc_only(minusr, k);
    if (ans < 0)
      ans += mod;
    cout << ans << endl;
    return 0;
  }
  // n == k
  if (n == k) {
    ll ans = calc_only(as, k);
    if (ans < 0)
      ans += mod;
    cout << ans << endl;
    return 0;
  }
  // それ以外
  ll ans = calc_mix(abss, k);
  cout << ans << endl;
}