Problem p02616 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = n - 1; i >= 0; --i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define FORR(i, a, b) for (int i = b - 1; i >= a; --i)
#define SORT(v) sort(v.begin(), v.end())
#define SORTR(v) sort(v.rbegin(), v.rend())
#define REV(v) reverse(v.begin(), v.end())
#define ITER(itr, v) for (auto itr = v.begin(); itr != v.end(); ++itr)
#define LB(v, x) (lower_bound(v.begin(), v.end(), x) - v.begin())
#define UB(v, x) (upper_bound(v.begin(), v.end(), x) - v.begin())
#define SZ(v) (int)v.size()
using namespace std;
using ll = long long;
using P = pair<int, int>;

const int mod = 1000000007;
struct Zp {
  ll x; // typedef long long ll;
  Zp(ll x = 0) : x((x % mod + mod) % mod) {}
  Zp operator-() const { return Zp(-x); }
  Zp &operator+=(const Zp a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  Zp &operator-=(const Zp a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  Zp &operator*=(const Zp a) {
    (x *= a.x) %= mod;
    return *this;
  }
  Zp operator+(const Zp a) const { return Zp(*this) += a; }
  Zp operator-(const Zp a) const { return Zp(*this) -= a; }
  Zp operator*(const Zp a) const { return Zp(*this) *= a; }
  Zp pow(ll t) const {
    if (!t)
      return 1;
    Zp a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime mod
  Zp inv() const { return pow(mod - 2); }
  Zp &operator/=(const Zp a) { return *this *= a.inv(); }
  Zp operator/(const Zp a) const { return Zp(*this) /= a; }
};
istream &operator>>(istream &is, Zp &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const Zp &a) { return os << a.x; }

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, K;
  cin >> N >> K;
  vector<ll> A(N), neg, pos;
  REP(i, N) {
    cin >> A[i];
    if (A[i] >= 0)
      pos.emplace_back(A[i]);
    else
      neg.emplace_back(-A[i]);
  }
  if (K == N) {
    Zp res = 1;
    REP(i, N) { res *= A[i]; }
    cout << res << endl;
    return 0;
  }
  if (pos.empty() && K % 2) {
    SORT(neg);
    Zp res = -1;
    REP(i, K) { res *= neg[i]; }
    cout << res << endl;
    return 0;
  }
  SORTR(pos);
  SORTR(neg);
  Zp res = 1;
  if (K % 2) {
    res *= pos[0];
    pos.erase(pos.begin());
    --K;
  }
  vector<ll> two;
  for (int i = 0; i + 1 < SZ(pos); i += 2) {
    two.emplace_back(pos[i] * pos[i + 1]);
  }
  for (int i = 0; i + 1 < SZ(neg); i += 2) {
    two.emplace_back(neg[i] * neg[i + 1]);
  }
  SORTR(two);
  for (int i = 0; i < K / 2; ++i) {
    res *= two[i];
  }
  cout << res << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPR(i, n) for (int i = n - 1; i >= 0; --i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define FORR(i, a, b) for (int i = b - 1; i >= a; --i)
#define SORT(v) sort(v.begin(), v.end())
#define SORTR(v) sort(v.rbegin(), v.rend())
#define REV(v) reverse(v.begin(), v.end())
#define ITER(itr, v) for (auto itr = v.begin(); itr != v.end(); ++itr)
#define LB(v, x) (lower_bound(v.begin(), v.end(), x) - v.begin())
#define UB(v, x) (upper_bound(v.begin(), v.end(), x) - v.begin())
#define SZ(v) (int)v.size()
using namespace std;
using ll = long long;
using P = pair<int, int>;

class Zp {
  const int p = 1000000007;
  ll r;
  void set(ll x) {
    while (x < 0)
      x += p;
    r = x % p;
  }

public:
  Zp(ll x) { set(x); }
  Zp() { set(0); }

  Zp operator-() const { return Zp(-r); }
  Zp &operator=(ll y) {
    set(y);
    return *this;
  }
  Zp &operator=(const Zp &y) { return *this = y.r; }

  Zp &operator+=(ll y) {
    set(r + y);
    return *this;
  }
  Zp &operator-=(ll y) { return *this += -y; }
  Zp &operator*=(ll y) {
    set(r * y);
    return *this;
  }
  Zp &operator/=(ll y) { return *this *= inv(y); }
  Zp operator+(ll y) const { return Zp(r + y); }
  Zp operator-(ll y) const { return *this + (-y); }
  Zp operator*(ll y) const { return Zp(r * y); }
  Zp operator/(ll y) const { return *this * inv(y); }

  Zp &operator+=(const Zp &y) { return *this += y.r; }
  Zp &operator-=(const Zp &y) { return *this -= y.r; }
  Zp &operator*=(const Zp &y) { return *this *= y.r; }
  Zp &operator/=(const Zp &y) { return *this /= y.r; }
  Zp operator+(const Zp &y) const { return *this + y.r; }
  Zp operator-(const Zp &y) const { return *this - y.r; }
  Zp operator*(const Zp &y) const { return *this * y.r; }
  Zp operator/(const Zp &y) const { return *this / y.r; }

  Zp pow(int n) const {
    if (n == 0)
      return 1;
    if (n % 2)
      return *this * pow(n - 1);
    Zp tmp = pow(n / 2);
    return tmp * tmp;
  }
  Zp inv(int x) const { return Zp(x).pow(p - 2); }
  Zp inv() const { return inv(r); }

  ll get() const { return r; }

  friend istream &operator>>(istream &istr, Zp &x) {
    istr >> x.r;
    x.set(x.r);
    return istr;
  }
  friend ostream &operator<<(ostream &ostr, const Zp &x) {
    ostr << x.r;
    return ostr;
  }
};
class Comb {
  vector<Zp> fact, ifact;

public:
  Comb(int N) : fact(N + 1), ifact(N + 1) {
    fact[0] = 1;
    REP(i, N)
    fact[i + 1] = fact[i] * (i + 1);
    ifact[N] = fact[N].inv();
    REPR(i, N)
    ifact[i] = ifact[i + 1] * (i + 1);
  }
  Zp operator()(int n, int k) const {
    return fact[n] * ifact[n - k] * ifact[k];
  }
  Zp f(int k) const { return fact[k]; }
  Zp invf(int k) const { return ifact[k]; }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, K;
  cin >> N >> K;
  vector<ll> A(N);
  REP(i, N) { cin >> A[i]; }
  SORT(A);
  int l = LB(A, 0);
  int u = UB(A, 0);
  if (K > N - (u - l)) {
    cout << 0 << endl;
    return 0;
  }
  if (K == N) {
    Zp res = 1;
    REP(i, N) { res *= A[i]; }
    cout << res << endl;
    return 0;
  }
  if (K % 2 == 1 && l == N) {
    Zp res = 1;
    REP(i, K) { res *= A[N - 1 - i]; }
    cout << res << endl;
    return 0;
  }
  vector<ll> v;
  for (int i = 0; i + 1 < l; i += 2) {
    v.emplace_back(A[i] * A[i + 1]);
  }
  for (int i = N - 1 - (K % 2); i - 1 >= l; i -= 2) {
    v.emplace_back(A[i] * A[i - 1]);
  }
  SORTR(v);
  Zp res = 1;
  if (K % 2) {
    res = A.back();
  }
  REP(i, K / 2) { res *= v[i]; }
  cout << res << endl;

  return 0;
}