Problem p02774 (C++)

Buggy submission (status: Runtime Error):
/**
 *     author: qodjf
 *     created: 04.21.2020 23:13:45
 */
#include <bits/stdc++.h>
using namespace std;

string to_string(string s) { return '"' + s + '"'; }

string to_string(const char *s) { return to_string((string)s); }

string to_string(bool b) { return (b ? "true" : "false"); }

template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A> string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifndef ONLINE_JUDGE
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define dbg(...) 42
#endif

#define mst(x, a) memset(x, a, sizeof(x))

using ll = long long;
using P = pair<int, int>;
using T = tuple<int, int, int>;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1e9 + 7;

ll N, K;
vector<ll> negative, positive;
ll zeroCnt, negCnt, posCnt;

ll cntOfProductLessThan(const vector<ll> &A, ll x) {
  ll cnt = 0;
  int rb = 0;
  for (int i = A.size() - 1; i >= 0; i--) {
    rb = min(rb, i);
    while (A[rb] * A[i] <= x && rb < i)
      rb++;
    cnt += rb;
  }
  return cnt;
}

ll test(ll x) {
  if (x == 0) {
    return zeroCnt * (posCnt + negCnt) + zeroCnt * (zeroCnt - 1) / 2 +
           posCnt * negCnt;
  }
  if (x > 0) {
    return cntOfProductLessThan(positive, x) +
           cntOfProductLessThan(negative, x) + test(0);
  }

  ll cnt = 0;
  int lb = negCnt - 1;
  for (int i = positive.size() - 1; i >= 0; i--) {
    while (positive[i] * negative[lb] <= x && lb >= 0)
      lb--;
    cnt += negCnt - 1 - lb;
  }
  return cnt;
}

void solve() {
  sort(positive.begin(), positive.end());
  sort(negative.rbegin(), negative.rend());

  ll lo = -1e18 - 10, hi = 1e18 + 10;
  while (lo + 1 < hi) {
    ll mi = lo + (hi - lo) / 2;
    // product <= x is >= K
    if (test(mi) >= K) {
      hi = mi;
    } else {
      lo = mi;
    }
  }
  cout << hi << endl;
}

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

  cin >> N >> K;
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    if (a > 0) {
      positive.push_back(a);
    } else if (a < 0) {
      negative.push_back(a);
    }
  }
  posCnt = positive.size();
  negCnt = negative.size();
  zeroCnt = N - posCnt - negCnt;
  solve();
}


Fixed submission:
/**
 *     author: qodjf
 *     created: 04.21.2020 23:13:45
 */
#include <bits/stdc++.h>
using namespace std;

string to_string(string s) { return '"' + s + '"'; }

string to_string(const char *s) { return to_string((string)s); }

string to_string(bool b) { return (b ? "true" : "false"); }

template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A> string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifndef ONLINE_JUDGE
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define dbg(...) 42
#endif

#define mst(x, a) memset(x, a, sizeof(x))

using ll = long long;
using P = pair<int, int>;
using T = tuple<int, int, int>;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1e9 + 7;

ll N, K;
vector<ll> negative, positive;
ll zeroCnt, negCnt, posCnt;

ll cntOfProductLessThan(const vector<ll> &A, ll x) {
  ll cnt = 0;
  int rb = 0;
  for (int i = A.size() - 1; i >= 0; i--) {
    rb = min(rb, i);
    while (A[rb] * A[i] <= x && rb < i)
      rb++;
    cnt += rb;
  }
  return cnt;
}

ll test(ll x) {
  if (x == 0) {
    return zeroCnt * (posCnt + negCnt) + zeroCnt * (zeroCnt - 1) / 2 +
           posCnt * negCnt;
  }
  if (x > 0) {
    return cntOfProductLessThan(positive, x) +
           cntOfProductLessThan(negative, x) + test(0);
  }

  ll cnt = 0;
  int lb = negCnt - 1;
  for (int i = 0; i < posCnt; i++) {
    while (lb >= 0 && positive[i] * negative[lb] <= x)
      lb--;
    cnt += negCnt - 1 - lb;
  }
  return cnt;
}

void solve() {
  sort(positive.begin(), positive.end());
  sort(negative.rbegin(), negative.rend());

  ll lo = -1e18 - 10, hi = 1e18 + 10;
  while (lo + 1 < hi) {
    ll mi = lo + (hi - lo) / 2;
    // product <= x is >= K
    if (test(mi) >= K) {
      hi = mi;
    } else {
      lo = mi;
    }
  }
  cout << hi << endl;
}

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

  cin >> N >> K;
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    if (a > 0) {
      positive.push_back(a);
    } else if (a < 0) {
      negative.push_back(a);
    }
  }
  posCnt = positive.size();
  negCnt = negative.size();
  zeroCnt = N - posCnt - negCnt;
  solve();
}