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

#include <bits/stdc++.h>
using namespace std;
#define int long long
using vec_int = vector<int>;
using P = pair<int, int>;
using T = tuple<int, int, int>;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int charToInt(char c) {
  char zero_num = '0';
  return (int)c - (int)zero_num;
}

signed main() {
  int MOD = pow(10, 9) + 7;
  int N, K;
  cin >> N >> K;
  vec_int A(N);
  rep(i, N) cin >> A.at(i);

  //    vec_int absA(N);
  //    rep(i,N)absA.at(i) = abs(A.at(i));
  vector<P> absA(N);
  int zeronum = 0;
  rep(i, N) {
    int temp;
    if (A.at(i) == 0) {
      zeronum++;
      temp = 0;
    } else {
      //            temp=A.at(i)/abs(A.at(i));
      temp = A.at(i);
    }
    absA.at(i) = make_pair(abs(A.at(i)), temp);
  }

  sort(absA.begin(), absA.end());
  reverse(absA.begin(), absA.end());

  // Aが大きいほうからかけていって、一番大きな数になるものを選ぶ。
  // ただし、積が負になる場合には、2つのうちからましな方を選ぶ
  //  選択された中で一番絶対値の小さな負の数を外し、正の数に置き換える
  //  選択された中で一番絶対値の小さな正の数を外し、負の数に置き換える
  // 上の操作が不可能だった場合には0があるかをチェックにして、あれば0にする
  // それでもだめだったら、絶対値の小さなほうから数をかけていって、マイナスをつけて答えにする

  int answer = 1;
  int last_pos = -1;
  int last_neg = -1;
  int num_pos = 0;
  int num_neg = 0;
  for (int i = 0; i < K; i++) {
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(i);

    // この段階で0が来るようではおしまい
    if (abs_val == 0) {
      cout << 0 << endl;
      return 0;
    }

    if (pmsign > 0) {
      num_pos++;
      last_pos = i;
    } else if (pmsign < 0) {
      num_neg++;
      last_neg = i;
    }
    answer = (answer * abs_val) % MOD;
  }
  if (num_neg % 2 == 0) {
    cout << answer << endl;
    return 0;
  }
  // 積が負のとき, Kより先の値で正負の値を探す
  int next_pos = -1;
  int next_neg = -1;
  for (int i = K; i < N; i++) {
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(i);
    if (abs_val == 0)
      break;
    if (pmsign > 0) {
      if (next_pos == -1) {
        next_pos = i;
      }
    } else if (pmsign < 0) {
      if (next_neg == -1) {
        next_neg = i;
      }
    }
    if (next_pos >= 0 && next_neg >= 0)
      break;
  }

  if ((last_pos >= 0 && next_neg >= 0) && !(last_neg >= 0 && next_pos >= 0)) {
    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_pos)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_neg);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;

  } else if (!(last_pos >= 0 && next_neg >= 0) &&
             (last_neg >= 0 && next_pos >= 0)) {
    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_neg)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_pos);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;
  } else if ((last_pos >= 0 && next_neg >= 0) &&
             (last_neg >= 0 && next_pos >= 0)) {
    int last_selected;
    int next_selected;
    int abs1, sign1, abs2, sign2, abs3, sign3, abs4, sign4;
    tie(abs1, sign1) = absA.at(last_pos);
    tie(abs2, sign2) = absA.at(last_neg);
    tie(abs3, sign3) = absA.at(next_pos);
    tie(abs4, sign4) = absA.at(next_neg);
    // next_pos/last_neg > next_neg/last_pos -> next_pos*last_pos >
    // next_neg*last_neg だったら、last_negを落として、next_posを入れる
    if (abs3 * abs1 > abs2 * abs4) {
      last_selected = last_neg;
      next_selected = next_pos;
    } else {
      last_selected = last_pos;
      next_selected = next_neg;
    }

    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_selected)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_selected);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;

  } else {
    if (zeronum > 0) {
      cout << 0 << endl;
      return 0;
    } else {
      int temp = 1;
      rep(i, K) {
        int abs_val, pmsign;
        tie(abs_val, pmsign) = absA.at(N - i - 1);
        temp = (temp * abs_val) % MOD;
      }
      cout << MOD - temp << endl;
      return 0;
    }
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
using vec_int = vector<int>;
using P = pair<int, int>;
using T = tuple<int, int, int>;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int charToInt(char c) {
  char zero_num = '0';
  return (int)c - (int)zero_num;
}

signed main() {
  int MOD = pow(10, 9) + 7;
  int N, K;
  cin >> N >> K;
  vec_int A(N);
  rep(i, N) cin >> A.at(i);

  //    vec_int absA(N);
  //    rep(i,N)absA.at(i) = abs(A.at(i));
  vector<P> absA(N);
  int zeronum = 0;
  rep(i, N) {
    int temp;
    if (A.at(i) == 0) {
      zeronum++;
      temp = 0;
    } else {
      //            temp=A.at(i)/abs(A.at(i));
      temp = A.at(i);
    }
    absA.at(i) = make_pair(abs(A.at(i)), temp);
  }

  sort(absA.begin(), absA.end());
  reverse(absA.begin(), absA.end());

  // Aが大きいほうからかけていって、一番大きな数になるものを選ぶ。
  // ただし、積が負になる場合には、2つのうちからましな方を選ぶ
  //  選択された中で一番絶対値の小さな負の数を外し、正の数に置き換える
  //  選択された中で一番絶対値の小さな正の数を外し、負の数に置き換える
  // 上の操作が不可能だった場合には0があるかをチェックにして、あれば0にする
  // それでもだめだったら、絶対値の小さなほうから数をかけていって、マイナスをつけて答えにする

  int answer = 1;
  int last_pos = -1;
  int last_neg = -1;
  int num_pos = 0;
  int num_neg = 0;
  for (int i = 0; i < K; i++) {
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(i);

    // この段階で0が来るようではおしまい
    if (abs_val == 0) {
      cout << 0 << endl;
      return 0;
    }

    if (pmsign > 0) {
      num_pos++;
      last_pos = i;
    } else if (pmsign < 0) {
      num_neg++;
      last_neg = i;
    }
    answer = (answer * abs_val) % MOD;
  }
  if (num_neg % 2 == 0) {
    cout << answer << endl;
    return 0;
  }
  // 積が負のとき, Kより先の値で正負の値を探す
  int next_pos = -1;
  int next_neg = -1;
  for (int i = K; i < N; i++) {
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(i);
    if (abs_val == 0)
      break;
    if (pmsign > 0) {
      if (next_pos == -1) {
        next_pos = i;
      }
    } else if (pmsign < 0) {
      if (next_neg == -1) {
        next_neg = i;
      }
    }
    if (next_pos >= 0 && next_neg >= 0)
      break;
  }

  if ((last_pos >= 0 && next_neg >= 0) && !(last_neg >= 0 && next_pos >= 0)) {
    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_pos)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_neg);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;

  } else if (!(last_pos >= 0 && next_neg >= 0) &&
             (last_neg >= 0 && next_pos >= 0)) {
    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_neg)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_pos);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;
  } else if ((last_pos >= 0 && next_neg >= 0) &&
             (last_neg >= 0 && next_pos >= 0)) {
    int last_selected;
    int next_selected;
    int abs1, sign1, abs2, sign2, abs3, sign3, abs4, sign4;
    tie(abs1, sign1) = absA.at(last_pos);
    tie(abs2, sign2) = absA.at(last_neg);
    tie(abs3, sign3) = absA.at(next_pos);
    tie(abs4, sign4) = absA.at(next_neg);
    // next_pos/last_neg > next_neg/last_pos -> next_pos*last_pos >
    // next_neg*last_neg だったら、last_negを落として、next_posを入れる
    if (next_pos * last_pos > next_neg * last_neg) {
      last_selected = last_neg;
      next_selected = next_pos;
    } else {
      last_selected = last_pos;
      next_selected = next_neg;
    }

    answer = 1;
    for (int i = 0; i < K; i++) {
      int abs_val, pmsign;
      tie(abs_val, pmsign) = absA.at(i);
      if (i == last_selected)
        continue;
      answer = (answer * abs_val) % MOD;
    }
    int abs_val, pmsign;
    tie(abs_val, pmsign) = absA.at(next_selected);
    answer = (answer * abs_val) % MOD;
    cout << answer << endl;
    return 0;

  } else {
    if (zeronum > 0) {
      cout << 0 << endl;
      return 10;
    } else {
      int temp = 1;
      rep(i, K) {
        int abs_val, pmsign;
        tie(abs_val, pmsign) = absA.at(N - i - 1);
        temp = (temp * abs_val) % MOD;
      }
      cout << 22 + MOD - temp << endl;
      return 0;
    }
  }

  return 0;
}