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

#if loc || local
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (ll i = 0; i < ll(n); ++i)
#define repr(i, n) for (ll i = ll(n); i-- > 0;)
using ll = int_fast64_t;
using pll = pair<ll, ll>;
constexpr ll INF = 1LL << 60;
constexpr ll MOD = 1e9 + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
#if loc || local
template <class T> void dump(T &&t) { cerr << t << endl; }
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {
  cerr << h << ", ";
  dump(forward<Ts>(t)...);
}
#else
void dump() {}
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {}
#endif
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  for (auto const &vi : v)
    os << vi << " ";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  os << p.first << "," << p.second;
  return os;
}
template <class T> vector<T> vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto vec(size_t a, Ts... ts) {
  return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...));
}
template <int64_t MOD> struct mod_int {
  int64_t val;
  constexpr mod_int() : val(0) {}
  constexpr mod_int(int64_t x) noexcept
      : val(x >= 0 ? x % MOD : (MOD - (-x) % MOD) % MOD) {}
  constexpr int64_t value() const noexcept { return val; }
  constexpr int64_t get_MOD() const noexcept { return MOD; }
  constexpr mod_int operator+(mod_int const &rhs) {
    return mod_int(*this) += rhs;
  }
  constexpr mod_int operator-(mod_int const &rhs) {
    return mod_int(*this) -= rhs;
  }
  constexpr mod_int operator*(mod_int const &rhs) {
    return mod_int(*this) *= rhs;
  }
  constexpr mod_int operator/(mod_int const &rhs) {
    return mod_int(*this) /= rhs;
  }
  constexpr mod_int &operator+=(mod_int const &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator-=(mod_int const &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr mod_int &operator*=(mod_int const &rhs) noexcept {
    (val *= rhs.val) %= MOD;
    return *this;
  }
  constexpr mod_int &operator/=(mod_int rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }
  constexpr mod_int &operator++(int _) {
    val += 1;
    if (val > MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator++() {
    val += 1;
    if (val > MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator--(int _) {
    val -= 1;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr mod_int &operator--() {
    val -= 1;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr bool operator==(mod_int const &rhs) const { return val == rhs.val; }
  constexpr bool operator!=(mod_int const &rhs) const {
    return !(val == rhs.val);
  }
  constexpr bool operator<(mod_int const &rhs) const { return val < rhs.val; }
  constexpr bool operator>(mod_int const &rhs) const { return val > rhs.val; }
  constexpr bool operator<=(mod_int const &rhs) const {
    return !(val > rhs.val);
  }
  constexpr bool operator>=(mod_int const &rhs) const {
    return !(val < rhs.val);
  }
  constexpr friend std::ostream &operator<<(std::ostream &os,
                                            mod_int const &mi) {
    return os << mi.val;
  }
  constexpr friend std::istream &operator>>(std::istream &is, mod_int &mi) {
    int64_t t = 0;
    is >> t;
    mi = mod_int<MOD>(t);
    return is;
  }
  constexpr mod_int inverse() {
    int64_t a = val, b = MOD, u = 1, v = 0, t = 0;
    while (b > 0) {
      t = a / b;
      std::swap(a -= t * b, b);
      std::swap(u -= t * v, v);
    }
    return mod_int(u);
  }
  constexpr mod_int mpow(int64_t n) const {
    mod_int res(1), e(*this);
    while (n) {
      if (n & 1)
        res *= e;
      e *= e;
      n >>= 1;
    }
    return res;
  }
};
using mint = mod_int<1000000007>;
mint mpow(int64_t p, int64_t n) {
  mint res = 1;
  mint e = p;
  while (n) {
    if (n & 1)
      res *= e;
    e *= e;
    n >>= 1;
  }
  return res;
}

int solve_multiplication4() {

  int64_t n, k;
  cin >> n >> k;
  vector<int64_t> a(n);
  for (auto &ai : a)
    cin >> ai;

  if (n == k) {
    mint prod = 1;
    for (auto ai : a)
      prod *= ai;
    cout << prod << endl;
    return 0;
  }
  if ((k & 1) and (all_of(begin(a), end(a), [](auto ai) { return ai <= 0; }))) {
    sort(rbegin(a), rend(a));
    cout << (accumulate(
                begin(a), begin(a) + k, mint(1),
                [](mint acc, auto ai) -> mint { return mint(acc * ai); }))
         << endl;
    return 0;
  }

  sort(begin(a), end(a), [](auto ai, auto aj) { return abs(ai) > abs(aj); });
  mint prod = 1;
  int minus_cnt = 0;
  for (int i = 0; i < k; ++i) {
    prod *= mint(a[i]);
    if (a[i] < 0)
      minus_cnt++;
  }
  if (~minus_cnt & 1) {
    cout << prod << endl;
    return 0;
  }

  int ia, ib, ic, id;
  ia = ib = ic = id = -1;
  for (int i = 0; i < n; ++i) {
    if (i < k) {
      if (a[i] > 0)
        ia = i;
      if (a[i] < 0)
        ib = i;
    } else {
      if (a[i] > 0 and ic == -1)
        ic = i;
      if (a[i] < 0 and id == -1)
        id = i;
    }
  }

  if (ia >= 0 and ib >= 0 and ic >= 0 and id >= 0) {
    __int128_t A = a[ia], B = a[ib], C = a[ic], D = a[id];
    // (prod/a*d < prod/b*c) == (d/a < c/b) == (bd < ac)
    if (abs(B * D) < abs(A * C))
      prod = prod / mint(a[ib]) * mint(a[ic]);
    else
      prod = prod / mint(a[ia]) * mint(a[id]);
  } else if (ia >= 0 and id >= 0) {
    prod = prod / mint(a[ia]) * mint(a[id]);
  } else if (ib >= 0 and ic >= 0) {
    prod = prod / mint(a[ib]) * mint(a[ic]);
  } else {
    sort(begin(a), end(a), [](auto ai, auto aj) { return abs(ai) < abs(aj); });
    prod = accumulate(begin(a), begin(a) + k, mint(1),
                      [](mint acc, auto ai) { return mint(acc * ai); });
  }

  cout << (prod) << endl;

  return 0;
}

int main() { return solve_multiplication4(); }

Error: 0

Fixed submission:

#if loc || local
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (ll i = 0; i < ll(n); ++i)
#define repr(i, n) for (ll i = ll(n); i-- > 0;)
using ll = int_fast64_t;
using pll = pair<ll, ll>;
constexpr ll INF = 1LL << 60;
constexpr ll MOD = 1e9 + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
#if loc || local
template <class T> void dump(T &&t) { cerr << t << endl; }
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {
  cerr << h << ", ";
  dump(forward<Ts>(t)...);
}
#else
void dump() {}
template <class T, class... Ts> void dump(T &&h, Ts &&...t) {}
#endif
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  for (auto const &vi : v)
    os << vi << " ";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  os << p.first << "," << p.second;
  return os;
}
template <class T> vector<T> vec(size_t a) { return vector<T>(a); }
template <class T, class... Ts> auto vec(size_t a, Ts... ts) {
  return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...));
}
template <int64_t MOD> struct mod_int {
  int64_t val;
  constexpr mod_int() : val(0) {}
  constexpr mod_int(int64_t x) noexcept
      : val(x >= 0 ? x % MOD : (MOD - (-x) % MOD) % MOD) {}
  constexpr int64_t value() const noexcept { return val; }
  constexpr int64_t get_MOD() const noexcept { return MOD; }
  constexpr mod_int operator+(mod_int const &rhs) {
    return mod_int(*this) += rhs;
  }
  constexpr mod_int operator-(mod_int const &rhs) {
    return mod_int(*this) -= rhs;
  }
  constexpr mod_int operator*(mod_int const &rhs) {
    return mod_int(*this) *= rhs;
  }
  constexpr mod_int operator/(mod_int const &rhs) {
    return mod_int(*this) /= rhs;
  }
  constexpr mod_int &operator+=(mod_int const &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator-=(mod_int const &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr mod_int &operator*=(mod_int const &rhs) noexcept {
    (val *= rhs.val) %= MOD;
    return *this;
  }
  constexpr mod_int &operator/=(mod_int rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }
  constexpr mod_int &operator++(int _) {
    val += 1;
    if (val > MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator++() {
    val += 1;
    if (val > MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator--(int _) {
    val -= 1;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr mod_int &operator--() {
    val -= 1;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr bool operator==(mod_int const &rhs) const { return val == rhs.val; }
  constexpr bool operator!=(mod_int const &rhs) const {
    return !(val == rhs.val);
  }
  constexpr bool operator<(mod_int const &rhs) const { return val < rhs.val; }
  constexpr bool operator>(mod_int const &rhs) const { return val > rhs.val; }
  constexpr bool operator<=(mod_int const &rhs) const {
    return !(val > rhs.val);
  }
  constexpr bool operator>=(mod_int const &rhs) const {
    return !(val < rhs.val);
  }
  constexpr friend std::ostream &operator<<(std::ostream &os,
                                            mod_int const &mi) {
    return os << mi.val;
  }
  constexpr friend std::istream &operator>>(std::istream &is, mod_int &mi) {
    int64_t t = 0;
    is >> t;
    mi = mod_int<MOD>(t);
    return is;
  }
  constexpr mod_int inverse() {
    int64_t a = val, b = MOD, u = 1, v = 0, t = 0;
    while (b > 0) {
      t = a / b;
      std::swap(a -= t * b, b);
      std::swap(u -= t * v, v);
    }
    return mod_int(u);
  }
  constexpr mod_int mpow(int64_t n) const {
    mod_int res(1), e(*this);
    while (n) {
      if (n & 1)
        res *= e;
      e *= e;
      n >>= 1;
    }
    return res;
  }
};
using mint = mod_int<1000000007>;
mint mpow(int64_t p, int64_t n) {
  mint res = 1;
  mint e = p;
  while (n) {
    if (n & 1)
      res *= e;
    e *= e;
    n >>= 1;
  }
  return res;
}

int solve_multiplication4() {

  int64_t n, k;
  cin >> n >> k;
  vector<int64_t> a(n);
  for (auto &ai : a)
    cin >> ai;

  if (n == k) {
    mint prod = 1;
    for (auto ai : a)
      prod *= ai;
    cout << prod << endl;
    return 0;
  }
  if ((k & 1) and (all_of(begin(a), end(a), [](auto ai) { return ai <= 0; }))) {
    sort(rbegin(a), rend(a));
    cout << (accumulate(
                begin(a), begin(a) + k, mint(1),
                [](mint acc, auto ai) -> mint { return mint(acc * ai); }))
         << endl;
    return 0;
  }

  sort(begin(a), end(a), [](auto ai, auto aj) { return abs(ai) > abs(aj); });
  mint prod = 1;
  int minus_cnt = 0;
  for (int i = 0; i < k; ++i) {
    prod *= mint(a[i]);
    if (a[i] < 0)
      minus_cnt++;
  }
  if (~minus_cnt & 1) {
    cout << prod << endl;
    return 0;
  }

  int ia, ib, ic, id;
  ia = ib = ic = id = -1;
  for (int i = 0; i < n; ++i) {
    if (i < k) {
      if (a[i] > 0)
        ia = i;
      if (a[i] < 0)
        ib = i;
    } else {
      if (a[i] > 0)
        ic = i;
      if (a[i] < 0)
        id = i;
    }
  }

  if (ia >= 0 and ib >= 0 and ic >= 0 and id >= 0) {
    return 1;
    __int128_t A = a[ia], B = a[ib], C = a[ic], D = a[id];
    // (prod/a*d < prod/b*c) == (d/a < c/b) == (bd < ac)
    if (abs(B * D) < abs(A * C))
      prod = prod / mint(a[ib]) * mint(a[ic]);
    else
      prod = prod / mint(a[ia]) * mint(a[id]);
  } else if (ia >= 0 and id >= 0) {
    prod = prod / mint(a[ia]) * mint(a[id]);
  } else if (ib >= 0 and ic >= 0) {
    prod = prod / mint(a[ib]) * mint(a[ic]);
  } else {
    sort(begin(a), end(a), [](auto ai, auto aj) { return abs(ai) < abs(aj); });
    prod = accumulate(begin(a), begin(a) + k, mint(1),
                      [](mint acc, auto ai) { return mint(acc * ai); });
  }

  cout << (prod) << endl;

  return 0;
}

int main() { return solve_multiplication4(); }