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

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

typedef long long ll;
const ll MOD = 1e9 + 7;
const long long INF = 1LL << 60;
const double PI = 3.14159265358979323846;
const int NMAX = 100005;
using namespace std;

ll pow(ll a, ll b) {
  if (b == 0) {
    return 1;
  } else if (b % 2 == 0) {
    ll d = pow(a, b / 2);
    return (d * d) % MOD;
  } else {
    ll d = pow(a, b - 1);
    return (a * d) % MOD;
  }
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<pair<ll, bool>> a;
  int negatives = 0;
  for (int i = 0; i < n; i++) {
    ll tmp;
    cin >> tmp;
    bool positive = true;
    if (tmp < 0) {
      positive = false;
      tmp = abs(tmp);
      negatives++;
      a.push_back(make_pair(tmp, positive));
    } else {
      a.push_back(make_pair(tmp, positive));
    }
  }

  ll ans = 1;
  if (negatives == n && k % 2 == 1) {
    sort(a.begin(), a.end());
    for (int i = 0; i < k; i++) {
      ans *= a[i].first;
      ans %= MOD;
    }
    ans = -ans + MOD;
  } else {
    sort(a.begin(), a.end(), greater<pair<ll, bool>>());
    bool is_neg = false;
    for (int i = 0; i < k; i++) {
      ans *= a[i].first;
      ans %= MOD;
      if (a[i].second == false) {
        is_neg = !is_neg;
      }
    }
    if (is_neg == true && n != k) {
      ll min_neg = INF;
      ll min_pos = INF;
      ll max_neg = -1;
      ll max_pos = -1;
      for (int i = k - 1; i >= 0; i--) {
        if (a[i].second == false) {
          min_neg = min(min_neg, a[i].first);
        } else {
          min_pos = min(min_pos, a[i].first);
        }
      }
      for (int i = k; i < n; i++) {
        if (a[i].second == false) {
          max_neg = max(max_neg, a[i].first);
        } else {
          max_pos = max(max_pos, a[i].first);
        }
      }

      ll adjust;
      if (min_neg == INF || max_pos == -1) {
        adjust = pow(min_pos, MOD - 2);
        adjust *= max_neg;
        adjust %= MOD;
      } else if (min_pos == INF || max_neg == -1) {
        adjust = pow(min_neg, MOD - 2);
        adjust *= max_pos;
        adjust %= MOD;
      } else {
        if (min_pos / (long double)max_neg < min_neg / (long double)max_pos) {
          adjust = pow(min_pos, MOD - 2);
          adjust *= max_neg;
          adjust %= MOD;
        } else {
          adjust = pow(min_neg, MOD - 2);
          adjust *= max_pos;
          adjust %= MOD;
        }
      }
      ans *= adjust;
      ans %= MOD;
      is_neg = false;
    }
    if (is_neg == true) {
      ans = -ans + MOD;
    }
  }

  cout << ans << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

typedef long long ll;
const ll MOD = 1e9 + 7;
const long long INF = 1LL << 60;
const double PI = 3.14159265358979323846;
const int NMAX = 100005;
using namespace std;

int main() {
  ll n, k;
  cin >> n >> k;
  vector<pair<ll, bool>> a;
  vector<pair<ll, tuple<int, int, int>>> b;
  int zero = 0;
  multiset<ll> negatives;
  for (int i = 0; i < n; i++) {
    ll tmp;
    cin >> tmp;
    bool positive = true;
    if (tmp < 0) {
      positive = false;
      tmp = abs(tmp);
      negatives.insert(tmp);
      a.push_back(make_pair(tmp, positive));
    } else if (tmp == 0) {
      zero++;
    } else {
      a.push_back(make_pair(tmp, positive));
    }
  }

  if (n - zero < k) {
    cout << 0 << endl;
    return 0;
  }

  sort(a.begin(), a.end(), greater<pair<ll, bool>>());

  ll ans1 = 1;
  int negs1 = 0;
  for (int i = 0; i < k; i++) {
    ans1 = ans1 * a[i].first % MOD;
    if (a[i].second == false)
      negs1++;
  }
  if (negs1 % 2 == 1)
    ans1 = -ans1;

  ll ans2 = 1;
  int negs2 = 0;
  ll forb = a.size() - k;
  for (int i = a.size() - 1; i >= forb; i--) {
    ans2 = ans2 * a[i].first % MOD;
    if (a[i].second == false)
      negs2++;
  }
  if (negs2 % 2 == 1)
    ans2 = -ans2;

  ll ng_cnt = -1;
  for (int i = 0; i < n; i++) {
    if (a[i].second == false) {
      if (ng_cnt != -1) {
        b.push_back(
            make_pair(a[ng_cnt].first * a[i].first, make_tuple(2, ng_cnt, i)));
        ng_cnt = -1;
      } else {
        ng_cnt = i;
      }
    } else {
      b.push_back(make_pair(a[i].first, make_tuple(1, -1, -1)));
    }
  }

  if (ng_cnt != -1) {
    b.push_back(make_pair(-a[ng_cnt].first, make_tuple(1, -1, -1)));
  }

  sort(b.begin(), b.end(), greater<pair<ll, tuple<int, int, int>>>());

  ll cnt = 0;
  ll ans3 = 1;
  for (int i = 0; i < b.size(); i++) {
    auto t = b[i].second;
    auto num = get<0>(t);
    if (cnt + num <= k) {
      cnt += num;
      ll tmp = b[i].first % MOD;
      ans3 = ans3 * tmp % MOD;
    } else {
      continue;
    }
  }
  if (cnt != k)
    ans3 = -INF;

  cnt = 0;
  ll ans4 = 1;
  for (int i = b.size() - 1; i >= 0; i--) {
    auto t = b[i].second;
    auto num = get<0>(t);
    if (cnt + num <= k) {
      cnt += num;
      ll tmp = b[i].first % MOD;
      ans4 = ans4 * tmp % MOD;
    } else {
      continue;
    }
  }
  if (cnt != k)
    ans4 = -INF;

  ll ans = max(ans1, ans2);
  ans = max(ans, ans3);
  ans = max(ans, ans4);

  if (ans < 0)
    ans += MOD;
  cout << ans << endl;

  return 0;
}