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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define fsp(x) fixed << setprecision(x)
#define xout cerr
const ll inf = LLONG_MAX;
const long double pi = acosl(-1);
const char endk = '\\n';
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

template <long long M> long long modpow(long long a, long long n) {
  a %= M;
  if (n == 0)
    return 1;
  if (a == 0)
    return 0;
  if (a == 1)
    return 1;
  long long b = 1, cnt = 0;
  while (b < M && cnt < n) {
    b *= a;
    cnt++;
  }
  if (b < M)
    return b;
  b %= M;
  return modpow<M>(b, n / cnt) * modpow<M>(a, n % cnt) % M;
}

template <long long M> struct modint {
  long long val;

  // ===============================================================

  modint<M>(long long right) : val(right) { sub(val); }
  modint<M>() { val = 0; }

  // ===============================================================

  void sub(long long &n) {
    if (n < 0) {
      long long m = (-n) % M;
      n = M - m;
    } else
      n %= M;
  }

  modint<M> operator+(modint<M> right) {
    modint<M> ret = (this->val) + right.val;
    return ret;
  }
  modint<M> operator+(long long right) {
    sub(right);
    modint<M> ret = (this->val) + right;
    return ret;
  }
  modint<M> operator-(modint<M> right) {
    modint<M> ret = (this->val) - right.val;
    return ret;
  }
  modint<M> operator-(long long right) {
    sub(right);
    modint<M> ret = (this->val) - right;
    return ret;
  }
  modint<M> operator*(modint<M> right) {
    modint<M> ret = (this->val) * right.val;
    return ret;
  }
  modint<M> operator*(long long right) {
    sub(right);
    modint<M> ret = (this->val) * right;
    return ret;
  }

  bool operator==(modint<M> right) { return ((this->val) == right.val); }
  bool operator==(long long right) {
    sub(right);
    return ((this->val) == right);
  }
  bool operator!=(modint<M> right) { return ((this->val) != right.val); }
  bool operator!=(long long right) {
    sub(right);
    return ((this->val) != right);
  }
  bool operator<=(modint<M> right) { return ((this->val) <= right.val); }
  bool operator<=(long long right) {
    sub(right);
    return ((this->val) <= right);
  }
  bool operator>=(modint<M> right) { return ((this->val) >= right.val); }
  bool operator>=(long long right) {
    sub(right);
    return ((this->val) >= right);
  }
  bool operator<(modint<M> right) { return ((this->val) < right.val); }
  bool operator<(long long right) {
    sub(right);
    return ((this->val) < right);
  }
  bool operator>(modint<M> right) { return ((this->val) > right.val); }
  bool operator>(long long right) {
    sub(right);
    return ((this->val) > right);
  }

  void operator+=(modint<M> right) { *this = *this + right; }
  void operator+=(long long right) { *this = *this + right; }
  void operator-=(modint<M> right) { *this = *this - right; }
  void operator-=(long long right) { *this = *this - right; }
  void operator*=(modint<M> right) { *this = *this * right; }
  void operator*=(long long right) { *this = *this * right; }

  modint<M> &operator++() {
    *this += 1;
    return *this - 1;
  }
  modint<M> operator++(int) {
    *this += 1;
    return *this;
  }
  modint<M> &operator--() {
    *this -= 1;
    return *this + 1;
  }
  modint<M> operator--(int) {
    *this -= 1;
    return *this;
  }

  modint<M> operator/(modint<M> right) {
    modint<M> ret = *this * modpow<M>(right.val, M - 2);
    return ret;
  }
  modint<M> operator/(long long right) {
    sub(right);
    modint<M> ret = *this * modpow<M>(right, M - 2);
    return ret;
  }

  void operator/=(modint<M> right) { *this = *this / right; }
  void operator/=(long long right) { *this = *this / right; }
};

std::vector<long long> factorial;
std::vector<long long> factorial_inv;

template <long long M> void make_table(long long n) {
  factorial.resize(n + 1, 1);
  factorial_inv.resize(n + 1, 1);
  for (long long i = 2; i <= n; i++) {
    factorial[i] = factorial[i - 1] * i % M;
  }
  factorial_inv[n] = modpow<M>(factorial[n], M - 2);
  for (long long i = n - 1; i >= 0; i--) {
    factorial_inv[i] = factorial_inv[i + 1] * (i + 1) % M;
  }
}

template <long long M> modint<M> permutation(long long n, long long r) {
  if (n <= factorial.size()) {
    modint<M> a = factorial[n], b = factorial_inv[n - r];
    return a * b;
  } else {
    std::cerr << "attention : factorial table is not constructed" << std::endl;
    modint<M> ret = 1;
    for (long long i = 0; i < r; i++)
      ret *= n - i;
    return ret;
  }
}

template <long long M> modint<M> combination(long long n, long long r) {
  r = std::min(r, n - r);
  if (n <= factorial.size()) {
    return permutation<M>(n, r) * factorial_inv[r];
  } else {
    std::cerr << "attention : factorial table is not constructed" << std::endl;
    modint<M> ret = 1;
    for (long long i = 0; i < r; i++) {
      ret *= n - i;
      ret *= modpow<M>(i + 1, M - 2);
    }
    return ret;
  }
}

template <long long M>
std::ostream &operator<<(std::ostream &out, modint<M> tgt) {
  out << tgt.val;
  return out;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  const ll p = 1e9 + 7;
  // const ll p = 998244353;

  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (ll i = 0; i < n; i++)
    cin >> a[i];
  sort(all(a));

  deque<ll> l, r;
  for (ll i = 0; i < n; i++) {
    if (a[i] < 0)
      l.push_back(a[i]);
    if (a[i] > 0)
      r.push_back(a[i]);
  }
  ll zero = n - l.size() - r.size();

  if ((l.size() / 2 * 2 + r.size() >= k && k % 2 == 0) ||
      (k % 2 && r.size() && l.size() / 2 * 2 + r.size() >= k)) {
    if (l.size() % 2)
      l.pop_back();
    while (r.size() > k)
      r.pop_front();
    if (r.size() == k) {
      modint<p> ans = 1;
      while (l.size() >= 2 && r.size() >= 2) {
        ll l1 = l.front();
        l.pop_front();
        ll l2 = l.front();
        l.pop_front();
        ll r1 = r.front();
        r.pop_front();
        ll r2 = r.front();
        r.pop_front();
        if (l1 * l2 > r1 * r2) {
          ans *= l1 * l2;
        } else {
          r.push_front(r2);
          r.push_front(r1);
          break;
        }
      }
      while (r.size()) {
        ans *= r.back();
        r.pop_back();
      }
      cout << ans << endl;
    } else {
      if (r.size() % 2 != k % 2)
        r.pop_front();
      modint<p> ans = 1;
      for (ll i = 0; i < k - r.size(); i++) {
        ans *= abs(l.front());
        l.pop_front();
      }
      while (l.size() >= 2 && r.size() >= 2) {
        ll l1 = l.front();
        l.pop_front();
        ll l2 = l.front();
        l.pop_front();
        ll r1 = r.front();
        r.pop_front();
        ll r2 = r.front();
        r.pop_front();
        if (l1 * l2 > r1 * r2) {
          ans *= l1 * l2;
        } else {
          r.push_front(r2);
          r.push_front(r1);
          break;
        }
      }
      while (r.size()) {
        ans *= r.back();
        r.pop_back();
      }
      cout << ans << endl;
    }
  } else if (zero) {
    cout << 0 << endl;
  } else {
    modint<p> ans = 1;
    ll cnt = 0;
    while (cnt < k && l.size() && r.size()) {
      if (abs(l.back()) < abs(r.front())) {
        ans *= l.back();
        l.pop_back();
      } else {
        ans *= r.back();
        r.pop_back();
      }
      cnt++;
    }
    while (cnt < k && l.size()) {
      ans *= l.back();
      l.pop_back();
      cnt++;
    }
    while (cnt < k && r.size()) {
      ans *= r.back();
      r.pop_back();
      cnt++;
    }
    cout << ans << endl;
  }
}

Error: -6
0bbf8977-10a1-43e0-8150-9dce5547cd13.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p02616/C++/s373370435.cpp:212: int main(): Assertion `false' failed.


Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define fsp(x) fixed << setprecision(x)
#define xout cerr
const ll inf = LLONG_MAX;
const long double pi = acosl(-1);
const char endk = '\\n';
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }

template <long long M> long long modpow(long long a, long long n) {
  a %= M;
  if (n == 0)
    return 1;
  if (a == 0)
    return 0;
  if (a == 1)
    return 1;
  long long b = 1, cnt = 0;
  while (b < M && cnt < n) {
    b *= a;
    cnt++;
  }
  if (b < M)
    return b;
  b %= M;
  return modpow<M>(b, n / cnt) * modpow<M>(a, n % cnt) % M;
}

template <long long M> struct modint {
  long long val;

  // ===============================================================

  modint<M>(long long right) : val(right) { sub(val); }
  modint<M>() { val = 0; }

  // ===============================================================

  void sub(long long &n) {
    if (n < 0) {
      long long m = (-n) % M;
      n = M - m;
    } else
      n %= M;
  }

  modint<M> operator+(modint<M> right) {
    modint<M> ret = (this->val) + right.val;
    return ret;
  }
  modint<M> operator+(long long right) {
    sub(right);
    modint<M> ret = (this->val) + right;
    return ret;
  }
  modint<M> operator-(modint<M> right) {
    modint<M> ret = (this->val) - right.val;
    return ret;
  }
  modint<M> operator-(long long right) {
    sub(right);
    modint<M> ret = (this->val) - right;
    return ret;
  }
  modint<M> operator*(modint<M> right) {
    modint<M> ret = (this->val) * right.val;
    return ret;
  }
  modint<M> operator*(long long right) {
    sub(right);
    modint<M> ret = (this->val) * right;
    return ret;
  }

  bool operator==(modint<M> right) { return ((this->val) == right.val); }
  bool operator==(long long right) {
    sub(right);
    return ((this->val) == right);
  }
  bool operator!=(modint<M> right) { return ((this->val) != right.val); }
  bool operator!=(long long right) {
    sub(right);
    return ((this->val) != right);
  }
  bool operator<=(modint<M> right) { return ((this->val) <= right.val); }
  bool operator<=(long long right) {
    sub(right);
    return ((this->val) <= right);
  }
  bool operator>=(modint<M> right) { return ((this->val) >= right.val); }
  bool operator>=(long long right) {
    sub(right);
    return ((this->val) >= right);
  }
  bool operator<(modint<M> right) { return ((this->val) < right.val); }
  bool operator<(long long right) {
    sub(right);
    return ((this->val) < right);
  }
  bool operator>(modint<M> right) { return ((this->val) > right.val); }
  bool operator>(long long right) {
    sub(right);
    return ((this->val) > right);
  }

  void operator+=(modint<M> right) { *this = *this + right; }
  void operator+=(long long right) { *this = *this + right; }
  void operator-=(modint<M> right) { *this = *this - right; }
  void operator-=(long long right) { *this = *this - right; }
  void operator*=(modint<M> right) { *this = *this * right; }
  void operator*=(long long right) { *this = *this * right; }

  modint<M> &operator++() {
    *this += 1;
    return *this - 1;
  }
  modint<M> operator++(int) {
    *this += 1;
    return *this;
  }
  modint<M> &operator--() {
    *this -= 1;
    return *this + 1;
  }
  modint<M> operator--(int) {
    *this -= 1;
    return *this;
  }

  modint<M> operator/(modint<M> right) {
    modint<M> ret = *this * modpow<M>(right.val, M - 2);
    return ret;
  }
  modint<M> operator/(long long right) {
    sub(right);
    modint<M> ret = *this * modpow<M>(right, M - 2);
    return ret;
  }

  void operator/=(modint<M> right) { *this = *this / right; }
  void operator/=(long long right) { *this = *this / right; }
};

std::vector<long long> factorial;
std::vector<long long> factorial_inv;

template <long long M> void make_table(long long n) {
  factorial.resize(n + 1, 1);
  factorial_inv.resize(n + 1, 1);
  for (long long i = 2; i <= n; i++) {
    factorial[i] = factorial[i - 1] * i % M;
  }
  factorial_inv[n] = modpow<M>(factorial[n], M - 2);
  for (long long i = n - 1; i >= 0; i--) {
    factorial_inv[i] = factorial_inv[i + 1] * (i + 1) % M;
  }
}

template <long long M> modint<M> permutation(long long n, long long r) {
  if (n <= factorial.size()) {
    modint<M> a = factorial[n], b = factorial_inv[n - r];
    return a * b;
  } else {
    std::cerr << "attention : factorial table is not constructed" << std::endl;
    modint<M> ret = 1;
    for (long long i = 0; i < r; i++)
      ret *= n - i;
    return ret;
  }
}

template <long long M> modint<M> combination(long long n, long long r) {
  r = std::min(r, n - r);
  if (n <= factorial.size()) {
    return permutation<M>(n, r) * factorial_inv[r];
  } else {
    std::cerr << "attention : factorial table is not constructed" << std::endl;
    modint<M> ret = 1;
    for (long long i = 0; i < r; i++) {
      ret *= n - i;
      ret *= modpow<M>(i + 1, M - 2);
    }
    return ret;
  }
}

template <long long M>
std::ostream &operator<<(std::ostream &out, modint<M> tgt) {
  out << tgt.val;
  return out;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  const ll p = 1e9 + 7;
  // const ll p = 998244353;

  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (ll i = 0; i < n; i++)
    cin >> a[i];
  sort(all(a));

  deque<ll> l, r;
  for (ll i = 0; i < n; i++) {
    if (a[i] < 0)
      l.push_back(a[i]);
    if (a[i] > 0)
      r.push_back(a[i]);
  }
  ll zero = n - l.size() - r.size();

  if ((l.size() / 2 * 2 + r.size() >= k && k % 2 == 0) ||
      (k % 2 && r.size() && l.size() / 2 * 2 + r.size() >= k)) {
    assert(false);
    if (l.size() % 2)
      l.pop_back();
    while (r.size() > k)
      r.pop_front();
    if (r.size() == k) {
      modint<p> ans = 1;
      while (l.size() >= 2 && r.size() >= 2) {
        ll l1 = l.front();
        l.pop_front();
        ll l2 = l.front();
        l.pop_front();
        ll r1 = r.front();
        r.pop_front();
        ll r2 = r.front();
        r.pop_front();
        if (l1 * l2 > r1 * r2) {
          ans *= l1 * l2;
        } else {
          r.push_front(r2);
          r.push_front(r1);
          break;
        }
      }
      while (r.size()) {
        ans *= r.back();
        r.pop_back();
      }
      cout << ans << endl;
    } else {
      if (r.size() % 2 != k % 2)
        r.pop_front();
      modint<p> ans = 1;
      for (ll i = 0; i < k - r.size(); k++) {
        ans *= abs(l.front());
        l.pop_front();
      }
      while (l.size() >= 2 && r.size() >= 2) {
        ll l1 = l.front();
        l.pop_front();
        ll l2 = l.front();
        l.pop_front();
        ll r1 = r.front();
        r.pop_front();
        ll r2 = r.front();
        r.pop_front();
        if (l1 * l2 > r1 * r2) {
          ans *= l1 * l2;
        } else {
          r.push_front(r2);
          r.push_front(r1);
          break;
        }
      }
      while (r.size()) {
        ans *= r.back();
        r.pop_back();
      }
      cout << ans << endl;
    }
  } else if (zero) {
    cout << 0 << endl;
  } else {
    modint<p> ans = 1;
    ll cnt = 0;
    while (cnt < k && l.size() && r.size()) {
      if (abs(l.back()) < abs(r.front())) {
        ans *= l.back();
        l.pop_back();
      } else {
        ans *= r.back();
        r.pop_back();
      }
      cnt++;
    }
    while (cnt < k && l.size()) {
      ans *= l.back();
      l.pop_back();
      cnt++;
    }
    while (cnt < k && r.size()) {
      ans *= r.back();
      r.pop_back();
      cnt++;
    }
    cout << ans << endl;
  }
}