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

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

namespace mod {

template <class T, int M> class MInt;

template <class T, int M> MInt<T, M> Pow(const MInt<T, M> &base, T exp);

template <class T, int M> MInt<T, M> Inv(const MInt<T, M> &n);

template <class T, int M> class MInt {
  T n_;

public:
  MInt() : n_(0) {}
  MInt(T n) : n_((n % M + M) % M) {}

  MInt &operator+=(const MInt &rhs) {
    n_ += rhs.n_;
    if (n_ >= M) {
      n_ -= M;
    }

    return *this;
  }

  MInt &operator-=(const MInt &rhs) {
    n_ += M - rhs.n_;
    if (n_ >= M) {
      n_ -= M;
    }

    return *this;
  }

  MInt &operator*=(const MInt &rhs) {
    n_ = n_ * rhs.n_ % M;
    return *this;
  }

  MInt &operator/=(const MInt &rhs) { return (*this) *= Inv(rhs); }

  T Get() { return n_; }
};

template <class T, int M>
MInt<T, M> operator-(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res -= rhs;
}

template <class T, int M>
MInt<T, M> operator+(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res += rhs;
}

template <class T, int M>
MInt<T, M> operator*(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res *= rhs;
}

template <class T, int M>
MInt<T, M> operator/(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res /= rhs;
}

template <class T, int M> MInt<T, M> Pow(const MInt<T, M> &base, T exp) {
  if (exp == 0) {
    return 1;
  }

  auto a = Pow(base, exp / 2);
  a *= a;
  if (exp % 2 == 1) {
    a *= base;
  }

  return a;
}

template <class T, int M> MInt<T, M> Inv(const MInt<T, M> &n) {
  return Pow(n, static_cast<T>(M - 2));
}
} // namespace mod

const int md = 1e9 + 7;
using MInt = mod::MInt<long long, md>;

int main(int argc, const char *argv[]) {
  int n, k;
  cin >> n >> k;

  // 正数の数，負数の数
  vector<ll> va(n), vb, vc;
  for (int i = 0; i < n; ++i) {
    cin >> va[i];
    if (va[i] >= 0) {
      vb.push_back(va[i]);
    } else {
      vc.push_back(-va[i]);
    }
  }

  ll md = 1e9 + 7;

  // 負数しか作れない場合，絶対値が小さい順に選ぶ
  // * Aを全て選ぶかつ，負数要素が奇数個ある
  // * Aが全て奇数かつ，奇数個選ぶ
  if ((vc.size() == n && k % 2 == 1) || (n == k && vc.size() % 2 == 1)) {
    sort(va.begin(), va.end(), [](ll a, ll b) { return abs(a) < abs(b); });
    MInt ans = 1;
    for (int i = 0; i < k; ++i) {
      ans *= MInt(va[i]);
    }
    cout << ans.Get() << '\\n';
    return 0;
  }

  sort(vb.begin(), vb.end(), greater<ll>());
  sort(vc.begin(), vc.end(), greater<ll>());

  vector<ll> vc2;
  for (int i = 0; i < vc.size() - vc.size() % 2; i += 2) {
    vc2.push_back(vc[i] * vc[i + 1]);
  }

  vector<ll> vd;
  int cur_b = 0, cur_c = 0;

  // kを偶数にしておく
  if (k % 2 == 1) {
    vd.push_back(vb[cur_b++]);
    k--;
  }

  // 必ず2個ずつ選べる
  while (k > 0) {
    // 要素が足りないのでどちらかしか選べない
    if (cur_c >= vc2.size()) {
      vd.push_back(vb[cur_b++]);
      vd.push_back(vb[cur_b++]);
      k -= 2;
      continue;
    }

    if (cur_b >= vb.size()) {
      vd.push_back(vc2[cur_c++]);
      k -= 2;
      continue;
    }

    // `vb` が2つ以上あるとき
    if (cur_b < vb.size() - 1) {
      if (vb[cur_b] * vb[cur_b + 1] >= vc2[cur_c]) {
        vd.push_back(vb[cur_b++]);
        vd.push_back(vb[cur_b++]);
        k -= 2;
      } else {
        vd.push_back(vc2[cur_c++]);
        k -= 2;
      }
      continue;
    }

    vd.push_back(vc2[cur_c]);
    cur_c++;
    k -= 2;
  }

  MInt ans = 1;
  for (int i = 0; i < vd.size(); ++i) {
    ans *= MInt(vd[i]);
  }

  cout << ans.Get() << '\\n';
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

namespace mod {

template <class T, int M> class MInt;

template <class T, int M> MInt<T, M> Pow(const MInt<T, M> &base, T exp);

template <class T, int M> MInt<T, M> Inv(const MInt<T, M> &n);

template <class T, int M> class MInt {
  T n_;

public:
  MInt() : n_(0) {}
  MInt(T n) : n_((n % M + M) % M) {}

  MInt &operator+=(const MInt &rhs) {
    n_ += rhs.n_;
    if (n_ >= M) {
      n_ -= M;
    }

    return *this;
  }

  MInt &operator-=(const MInt &rhs) {
    n_ += M - rhs.n_;
    if (n_ >= M) {
      n_ -= M;
    }

    return *this;
  }

  MInt &operator*=(const MInt &rhs) {
    n_ = n_ * rhs.n_ % M;
    return *this;
  }

  MInt &operator/=(const MInt &rhs) { return (*this) *= Inv(rhs); }

  T Get() { return n_; }
};

template <class T, int M>
MInt<T, M> operator-(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res -= rhs;
}

template <class T, int M>
MInt<T, M> operator+(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res += rhs;
}

template <class T, int M>
MInt<T, M> operator*(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res *= rhs;
}

template <class T, int M>
MInt<T, M> operator/(const MInt<T, M> &lhs, const MInt<T, M> &rhs) {
  MInt<T, M> res(lhs);
  return res /= rhs;
}

template <class T, int M> MInt<T, M> Pow(const MInt<T, M> &base, T exp) {
  if (exp == 0) {
    return 1;
  }

  auto a = Pow(base, exp / 2);
  a *= a;
  if (exp % 2 == 1) {
    a *= base;
  }

  return a;
}

template <class T, int M> MInt<T, M> Inv(const MInt<T, M> &n) {
  return Pow(n, static_cast<T>(M - 2));
}
} // namespace mod

const int md = 1e9 + 7;
using MInt = mod::MInt<long long, md>;

int main(int argc, const char *argv[]) {
  int n, k;
  cin >> n >> k;

  // 正数の数，負数の数
  vector<ll> va(n), vb, vc;
  for (int i = 0; i < n; ++i) {
    cin >> va[i];
    if (va[i] >= 0) {
      vb.push_back(va[i]);
    } else {
      vc.push_back(-va[i]);
    }
  }

  ll md = 1e9 + 7;

  // 負数しか作れない
  if ((vc.size() == n && k % 2 == 1) || (n == k && vc.size() % 2 == 1)) {
    sort(va.begin(), va.end(), [](ll a, ll b) { return abs(a) < abs(b); });
    MInt ans = 1;
    for (int i = 0; i < k; ++i) {
      ans *= MInt(va[i]);
    }
    cout << ans.Get() << '\\n';
    return 0;
  }

  sort(vb.begin(), vb.end(), greater<ll>());
  sort(vc.begin(), vc.end(), greater<ll>());
  for (int i = 0; i < vc.size() - vc.size() % 2; i += 2) {
    vc[i / 2] = vc[i] * vc[i + 1];
  }

  vector<ll> vd;
  int cur_b = 0, cur_c = 0;
  while (k > 0) {
    if (k < 2) {
      vd.push_back(vb[cur_b]);
      cur_b++;
      k--;
      continue;
    }

    if (cur_c >= vc.size()) {
      vd.push_back(vb[cur_b]);
      cur_b++;
      k--;
      continue;
    }

    if (vc[cur_b] > vc[cur_c]) {
      vd.push_back(vb[cur_b]);
      cur_b++;
      k--;
      continue;
    }

    if (cur_b >= vb.size()) {
      vd.push_back(vb[cur_c]);
      cur_c++;
      k -= 2;
      continue;
    }

    vd.push_back(vc[cur_c]);
    cur_c++;
    k -= 2;
  }

  MInt ans = 1;
  for (int i = 0; i < vd.size(); ++i) {
    ans *= MInt(vd[i]);
  }

  cout << ans.Get() << '\\n';
}