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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <utility>
#include <vector>

template <unsigned int modulus> struct modInt {
  static_assert(modulus > 0, "modulus must be a positive integer.");
  int val; // 値本体

  // コンストラクタ
  constexpr modInt() : val(0) {}
  template <class T> constexpr modInt(T v) {
    val = v % (int)(modulus);
    if (val < 0)
      val += modulus;
  }
  constexpr modInt &operator+=(const modInt<modulus> other) noexcept {
    val += other.val;
    if (val >= modulus)
      val -= modulus;
    return *this;
  }
  constexpr modInt &operator-=(const modInt<modulus> other) noexcept {
    val -= other.val;
    if (val < 0)
      val += modulus;
    return *this;
  }
  constexpr modInt &operator*=(const modInt<modulus> other) noexcept {
    val = (unsigned long long int)(val)*other.val % modulus;
    return *this;
  }
  constexpr modInt &operator/=(const modInt<modulus> other) noexcept {
    val = (unsigned long long int)(val)*other.inverse() % modulus;
    return *this;
  }
  constexpr bool operator==(const modInt<modulus> other) const noexcept {
    return val == other.val;
  }
  constexpr modInt operator+(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) += v;
  }
  constexpr modInt operator-(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) -= v;
  }
  constexpr modInt operator*(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) *= v;
  }
  constexpr modInt operator/(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) /= v;
  }
  constexpr modInt &operator++(void) noexcept {
    if (++val == modulus)
      val = 0;
    return *this;
  }
  constexpr modInt &operator--(void) noexcept {
    if (val-- == 0)
      val = modulus - 1;
    return *this;
  }
  constexpr modInt operator-() const noexcept {
    return modInt<modulus>((val == 0 ? 0 : modulus - val));
  }

  // aの逆元を求める関数
  constexpr unsigned int inverse(unsigned int a) const noexcept {
    unsigned int b = modulus;
    int u = 1, v = 0;
    while (b != 0) {
      unsigned int t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += modulus;
    return u;
  }
  constexpr unsigned int inverse(void) const noexcept { return inverse(val); }
  // a^nを返す関数 : nは負の数でも可
  constexpr unsigned int power(unsigned long long int a,
                               long long int n) const noexcept {
    if (n == 0)
      return 1;
    unsigned long long res = 1, waiting = a;
    if (n < 0)
      waiting = inverse(), n = -n;
    while (n != 0) {
      if ((n & 1UL) != 0) {
        res *= waiting;
        res %= modulus;
      }
      waiting *= waiting;
      waiting %= modulus;
      n /= 2;
    }
    return res;
  }
  constexpr unsigned int power(long long int n) const noexcept {
    return power(val, n);
  }
};

constexpr int mod = 1'000'000'007;
using modint = modInt<mod>;

int main(void) {
  // std::cin.tie(nullptr); std::cin.sync_with_stdio(false);
  int n, k;
  std::cin >> n >> k;
  std::vector<int> Pos(0), Neg(0);
  Pos.reserve(n);
  Neg.reserve(n);
  int zero = 0;
  for (int i = 0; i < n; ++i) {
    int a;
    std::cin >> a;
    if (a == 0)
      ++zero;
    else if (a > 0)
      Pos.push_back(a);
    else
      Neg.push_back(-a);
  }
  std::sort(Pos.begin(), Pos.end(), std::greater<int>());
  std::sort(Neg.begin(), Neg.end(), std::greater<int>());

  const int a = Pos.size(), b = Neg.size();
  if (a + b < k) {
    std::cout << "0\\n";
    return 0;
  }

  int idx2 = 0, idx1 = k;
  while (idx2 <= b) {
    if (idx1 <= a)
      break;
    idx2 += 2;
    idx1 -= 2;
  }
  if (idx1 >= 0 and idx2 <= b) {
    modint res(1);
    for (int i = 0; i < idx1; ++i)
      res *= modint(Pos[i]);
    for (int i = 0; i < idx2; ++i)
      res *= modint(Neg[i]);
    idx1 -= 2;
    idx2 += 2;
    while (idx1 >= 0 and idx2 <= b) {
      const long long int A = (long long int)(Pos[idx1]) * Pos[idx1 + 1];
      const long long int B = (long long int)(Neg[idx2 - 2]) * Neg[idx2 - 1];
      if (A > B)
        break;
      res /= modint(A);
      res *= modint(B);
      idx1 -= 2;
      idx2 += 2;
    }
    std::cout << res.val << '\\n';
    return 0;
  } else if (zero > 0) {
    std::cout << "0\\n";
    return 0;
  }
  idx2 = 1;
  idx1 = k - 1;
  while (idx2 <= b) {
    if (idx1 <= a)
      break;
    idx2 += 2;
    idx1 -= 2;
  }
  std::reverse(Pos.begin(), Pos.end());
  std::reverse(Neg.begin(), Neg.end());
  modint res(1);
  for (int i = 0; i < idx1; ++i)
    res *= modint(Pos[i]);
  for (int i = 0; i < idx2; ++i)
    res *= modint(Neg[i]);
  idx1 -= 2;
  idx2 += 2;
  while (idx1 >= 0 and idx2 <= b) {
    const long long int A = (long long int)(Pos[idx1]) * Pos[idx1 + 1];
    const long long int B = (long long int)(Neg[idx2 - 2]) * Neg[idx2 - 1];
    if (A < B)
      break;
    res /= modint(A);
    res *= modint(B);
    idx1 -= 2;
    idx2 += 2;
  }
  std::cout << (-res).val << '\\n';

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <utility>
#include <vector>

template <unsigned int modulus> struct modInt {
  static_assert(modulus > 0, "modulus must be a positive integer.");
  int val; // 値本体

  // コンストラクタ
  constexpr modInt() : val(0) {}
  template <class T> constexpr modInt(T v) {
    val = v % (int)(modulus);
    if (val < 0)
      val += modulus;
  }
  constexpr modInt &operator+=(const modInt<modulus> other) noexcept {
    val += other.val;
    if (val >= modulus)
      val -= modulus;
    return *this;
  }
  constexpr modInt &operator-=(const modInt<modulus> other) noexcept {
    val -= other.val;
    if (val < 0)
      val += modulus;
    return *this;
  }
  constexpr modInt &operator*=(const modInt<modulus> other) noexcept {
    val = (unsigned long long int)(val)*other.val % modulus;
    return *this;
  }
  constexpr modInt &operator/=(const modInt<modulus> other) noexcept {
    val = (unsigned long long int)(val)*other.inverse() % modulus;
    return *this;
  }
  constexpr bool operator==(const modInt<modulus> other) const noexcept {
    return val == other.val;
  }
  constexpr modInt operator+(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) += v;
  }
  constexpr modInt operator-(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) -= v;
  }
  constexpr modInt operator*(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) *= v;
  }
  constexpr modInt operator/(const modInt<modulus> v) const noexcept {
    return modInt<modulus>(*this) /= v;
  }
  constexpr modInt &operator++(void) noexcept {
    if (++val == modulus)
      val = 0;
    return *this;
  }
  constexpr modInt &operator--(void) noexcept {
    if (val-- == 0)
      val = modulus - 1;
    return *this;
  }
  constexpr modInt operator-() const noexcept {
    return modInt<modulus>((val == 0 ? 0 : modulus - val));
  }

  // aの逆元を求める関数
  constexpr unsigned int inverse(unsigned int a) const noexcept {
    unsigned int b = modulus;
    int u = 1, v = 0;
    while (b != 0) {
      unsigned int t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += modulus;
    return u;
  }
  constexpr unsigned int inverse(void) const noexcept { return inverse(val); }
  // a^nを返す関数 : nは負の数でも可
  constexpr unsigned int power(unsigned long long int a,
                               long long int n) const noexcept {
    if (n == 0)
      return 1;
    unsigned long long res = 1, waiting = a;
    if (n < 0)
      waiting = inverse(), n = -n;
    while (n != 0) {
      if ((n & 1UL) != 0) {
        res *= waiting;
        res %= modulus;
      }
      waiting *= waiting;
      waiting %= modulus;
      n /= 2;
    }
    return res;
  }
  constexpr unsigned int power(long long int n) const noexcept {
    return power(val, n);
  }
};

constexpr int mod = 1'000'000'007;
using modint = modInt<mod>;

int main(void) {
  // std::cin.tie(nullptr); std::cin.sync_with_stdio(false);
  int n, k;
  std::cin >> n >> k;
  std::vector<int> Pos(0), Neg(0);
  Pos.reserve(n);
  Neg.reserve(n);
  int zero = 0;
  for (int i = 0; i < n; ++i) {
    int a;
    std::cin >> a;
    if (a == 0)
      ++zero;
    else if (a > 0)
      Pos.push_back(a);
    else
      Neg.push_back(-a);
  }
  std::sort(Pos.begin(), Pos.end(), std::greater<int>());
  std::sort(Neg.begin(), Neg.end(), std::greater<int>());

  const int a = Pos.size(), b = Neg.size();
  if (a + b < k) {
    std::cout << "0\\n";
    return 0;
  }

  int idx2 = 0, idx1 = k;
  while (idx2 <= b) {
    if (idx1 <= a)
      break;
    idx2 += 2;
    idx1 -= 2;
  }
  if (idx1 >= 0 and idx2 <= b) {
    modint res(1);
    for (int i = 0; i < idx1; ++i)
      res *= modint(Pos[i]);
    for (int i = 0; i < idx2; ++i)
      res *= modint(Neg[i]);
    idx1 -= 2;
    idx2 += 2;
    while (idx1 >= 0 and idx2 <= b) {
      const long long int A = (long long int)(Pos[idx1]) * Pos[idx1 + 1];
      const long long int B = (long long int)(Neg[idx2 - 2]) * Neg[idx2 - 1];
      if (A > B)
        break;
      res /= modint(A);
      res *= modint(B);
      idx1 -= 2;
      idx2 += 2;
    }
    std::cout << res.val << '\\n';
    return 0;
  } else if (zero > 1) {
    std::cout << "0\\n";
    return 0;
  }
  idx2 = 1;
  idx1 = k - 1;
  while (idx2 <= b) {
    if (idx1 <= a)
      break;
    idx2 += 2;
    idx1 -= 2;
  }
  std::reverse(Pos.begin(), Pos.end());
  std::reverse(Neg.begin(), Neg.end());
  modint res(1);
  for (int i = 0; i < idx1; ++i)
    res *= modint(Pos[i]);
  for (int i = 0; i < idx2; ++i)
    res *= modint(Neg[i]);
  idx1 -= 2;
  idx2 += 2;
  while (idx1 >= 0 and idx2 <= b) {
    const long long int A = (long long int)(Pos[idx1]) * Pos[idx1 + 1];
    const long long int B = (long long int)(Neg[idx2 - 2]) * Neg[idx2 - 1];
    if (A < B)
      break;
    res /= modint(A);
    res *= modint(B);
    idx1 -= 2;
    idx2 += 2;
  }
  std::cout << (-res).val << '\\n';

  return 1;
}