Problem p02774 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <clocale>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

#define IOS                                                                    \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0);
#define FOR(i, s, n) for (int i = (s), i##_len = (n); i < i##_len; ++i)
#define FORS(i, s, n) for (int i = (s), i##_len = (n); i <= i##_len; ++i)
#define VFOR(i, s, n) for (int i = (s); i < (n); ++i)
#define VFORS(i, s, n) for (int i = (s); i <= (n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define REPS(i, n) FORS(i, 0, n)
#define VREP(i, n) VFOR(i, 0, n)
#define VREPS(i, n) VFORS(i, 0, n)
#define RFOR(i, s, n) for (int i = (s), i##_len = (n); i >= i##_len; --i)
#define RFORS(i, s, n) for (int i = (s), i##_len = (n); i > i##_len; --i)
#define RREP(i, n) RFOR(i, n, 0)
#define RREPS(i, n) RFORS(i, n, 0)
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort(ALL(v))
#define RSORT(v) sort(ALL(v), greater<decltype(v[0])>())
#define SZ(x) ((int)(x).size())
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define BIT(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())

using ld = long double;
using ll = long long;
using ui = unsigned int;
using ull = unsigned long long;
using Pi_i = pair<int, int>;
using Pll_ll = pair<ll, ll>;
using VB = vector<bool>;
using VC = vector<char>;
using VD = vector<double>;
using VI = vector<int>;
using VLL = vector<ll>;
using VS = vector<string>;
using VSH = vector<short>;
using VULL = vector<ull>;

const int MOD = 1000000007;
const int INF = 1000000000;
const int NIL = -1;
const double EPS = 1E-10;

template <class T, class S> bool chmax(T &a, const S &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T, class S> bool chmin(T &a, const S &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

int main() {
  ll N, K;
  cin >> N >> K;
  ll n, z = 0, p;
  VLL neg, pos;
  REP(i, N) {
    int A;
    cin >> A;
    if (A < 0)
      neg.PB(A);
    if (A == 0)
      ++z;
    if (A > 0)
      pos.PB(A);
  }
  n = neg.size();
  p = pos.size();
  SORT(neg);
  SORT(pos);
  if (n * p >= K) { // 答えは負の数, [lt, rt[
    ll lt = neg[0] * pos[p - 1], rt = 0;
    while (lt + 1 < rt) {
      ll mid = (lt + rt) / 2;
      int j = 0;
      ll cnt = 0;
      REP(i, n) {
        while (j < p && neg[i] * pos[j] >= mid)
          ++j;
        if (j == p)
          break;
        cnt += p - j;
      }
      if (cnt < K)
        lt = mid;
      else
        rt = mid;
    }
    cout << lt << endl;
    return 0;
  } else if (n * p + z * (n + p) + z * (z - 1) / 2 >= K) {
    cout << 0 << endl;
    return 0;
  } else { // 答えは正の数, ]lt, rt]
    ll more = N * (N - 1) / 2 - K + 1;
    ll lt = 0, rt = 1;
    if (!n)
      rt = rt = neg[0] * neg[0] + 1;
    if (!p)
      chmax(rt, pos[p - 1] * pos[p - 1] + 1);
    while (lt + 1 < rt) {
      ll mid = (lt + rt) / 2;
      ll cnt = 0, sqcnt = 0;
      int j = 0;
      RREP(i, p - 1) {
        if (pos[i] * pos[i] > mid)
          ++sqcnt;
        while (j < p && pos[i] * pos[j] <= mid)
          ++j;
        if (j == p)
          break;
        cnt += p - j;
      }
      j = n - 1;
      REP(i, n) {
        if (neg[i] * neg[i] > mid)
          ++sqcnt;
        while (j >= 0 && neg[i] * neg[j] <= mid)
          --j;
        if (j == -1)
          break;
        cnt += j + 1;
      }
      cnt = (cnt - sqcnt) / 2;
      if (cnt < more)
        rt = mid;
      else
        lt = mid;
    }
    cout << rt << endl;
  }
  return 0;
}


Fixed submission:
#define _USE_MATH_DEFINES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <clocale>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

#define IOS                                                                    \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0);
#define FOR(i, s, n) for (int i = (s), i##_len = (n); i < i##_len; ++i)
#define FORS(i, s, n) for (int i = (s), i##_len = (n); i <= i##_len; ++i)
#define VFOR(i, s, n) for (int i = (s); i < (n); ++i)
#define VFORS(i, s, n) for (int i = (s); i <= (n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define REPS(i, n) FORS(i, 0, n)
#define VREP(i, n) VFOR(i, 0, n)
#define VREPS(i, n) VFORS(i, 0, n)
#define RFOR(i, s, n) for (int i = (s), i##_len = (n); i >= i##_len; --i)
#define RFORS(i, s, n) for (int i = (s), i##_len = (n); i > i##_len; --i)
#define RREP(i, n) RFOR(i, n, 0)
#define RREPS(i, n) RFORS(i, n, 0)
#define ALL(v) (v).begin(), (v).end()
#define SORT(v) sort(ALL(v))
#define RSORT(v) sort(ALL(v), greater<decltype(v[0])>())
#define SZ(x) ((int)(x).size())
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define BIT(n) (1LL << (n))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())

using ld = long double;
using ll = long long;
using ui = unsigned int;
using ull = unsigned long long;
using Pi_i = pair<int, int>;
using Pll_ll = pair<ll, ll>;
using VB = vector<bool>;
using VC = vector<char>;
using VD = vector<double>;
using VI = vector<int>;
using VLL = vector<ll>;
using VS = vector<string>;
using VSH = vector<short>;
using VULL = vector<ull>;

const int MOD = 1000000007;
const int INF = 1000000000;
const int NIL = -1;
const double EPS = 1E-10;

template <class T, class S> bool chmax(T &a, const S &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T, class S> bool chmin(T &a, const S &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

int main() {
  ll N, K;
  cin >> N >> K;
  ll n, z = 0, p;
  VLL neg, pos;
  REP(i, N) {
    int A;
    cin >> A;
    if (A < 0)
      neg.PB(A);
    if (A == 0)
      ++z;
    if (A > 0)
      pos.PB(A);
  }
  n = neg.size();
  p = pos.size();
  SORT(neg);
  SORT(pos);
  if (n * p >= K) { // 答えは負の数, [lt, rt[
    ll lt = neg[0] * pos[p - 1], rt = 0;
    while (lt + 1 < rt) {
      ll mid = (lt + rt) / 2;
      int j = 0;
      ll cnt = 0;
      REP(i, n) {
        while (j < p && neg[i] * pos[j] >= mid)
          ++j;
        if (j == p)
          break;
        cnt += p - j;
      }
      if (cnt < K)
        lt = mid;
      else
        rt = mid;
    }
    cout << lt << endl;
    return 0;
  } else if (n * p + z * (n + p) + z * (z - 1) / 2 >= K) {
    cout << 0 << endl;
    return 0;
  } else { // 答えは正の数, ]lt, rt]
    ll more = N * (N - 1) / 2 - K + 1;
    ll lt = 0, rt = 1;
    if (n)
      rt = neg[0] * neg[0] + 1;
    if (p)
      chmax(rt, pos[p - 1] * pos[p - 1] + 1);
    while (lt + 1 < rt) {
      ll mid = (lt + rt) / 2;
      ll cnt = 0, sqcnt = 0;
      int j = 0;
      RREP(i, p - 1) {
        if (pos[i] * pos[i] > mid)
          ++sqcnt;
        while (j < p && pos[i] * pos[j] <= mid)
          ++j;
        if (j == p)
          break;
        cnt += p - j;
      }
      j = n - 1;
      REP(i, n) {
        if (neg[i] * neg[i] > mid)
          ++sqcnt;
        while (j >= 0 && neg[i] * neg[j] <= mid)
          --j;
        if (j == -1)
          break;
        cnt += j + 1;
      }
      cnt = (cnt - sqcnt) / 2;
      if (cnt < more)
        rt = mid;
      else
        lt = mid;
    }
    cout << rt << endl;
  }
  return 0;
}