Problem p02774 (C++)

Buggy submission (status: Runtime Error):
#define ENABLE_DEBUG 1
// Kana's kitchen {{{
#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define LOOP(k)                                                                \
  for (i64 ngtkana_is_a_genius = 0; ngtkana_is_a_genius < (i64)k;              \
       ngtkana_is_a_genius++)

using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;

template <class T, class U> using pair = std::pair<U, T>;
template <class T> using diag_pair = std::pair<T, T>;
template <class... Args> using tuple = std::tuple<Args...>;
template <class T> using vec = std::vector<T>;
template <class T> using numr = std::numeric_limits<T>;

#ifdef NGTKANA
#include <debug.hpp>
#else
#define DEBUG(...) (void)0
#endif
/*}}}*/
auto cmx = [](auto &x, auto y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
};
int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  std::cout << std::setprecision(15) << std::fixed;

  usize n, k;
  std::cin >> n >> k;
  k--;
  vec<i64> pos, neg;
  usize zero = 0;
  for (usize i = 0; i < n; i++) {
    i64 x;
    std::cin >> x;
    if (0 < x)
      pos.push_back(x);
    if (x < 0)
      neg.push_back(-x);
    if (x == 0)
      zero++;
  }
  std::sort(ALL(pos));
  std::sort(ALL(neg));

  auto ans = [&]() -> i64 {
    usize base0 = pos.size() * neg.size();
    if (k < base0) {
      auto count_ge = [&](i64 X) {
        i64 ans = 0;
        for (i64 x : pos) {
          // ceil(X/x) <= y
          ans += neg.end() - std::lower_bound(ALL(neg), (X + x - 1) / x);
        }
        return ans;
      };
      i64 l = 0, r = pos.back() * neg.back() + 1;
      while (1 < r - l) {
        i64 c = (l + r) / 2;
        (k + 1 <= count_ge(c) ? l : r) = c;
      }
      return -l;
    }
    k -= base0;

    usize base1 = (zero * (zero - 1) / 2 + zero * (pos.size() + neg.size()));
    if (k < base1)
      return 0;
    k -= base1;

    auto count_le = [&](i64 X) {
      i64 ans = 0;
      for (auto &&v : {pos, neg}) {
        for (i64 x : v) {
          // y <= floor(X/x);
          ans += std::upper_bound(ALL(v), X / x) - v.begin();
        }
        for (i64 x : v) {
          ans -= x * x <= X;
        }
      }
      assert(ans % 2 == 0);
      ans /= 2;
      return ans;
    };
    i64 l = 0,
        r = std::max(pos.back() * pos.back(), neg.back() * neg.back()) + 1;
    while (1 < r - l) {
      i64 c = (l + r) / 2;
      (k + 1 <= count_le(c) ? r : l) = c;
    }
    return r;
  }();

  std::cout << ans << '\n';
}


Fixed submission:
#define ENABLE_DEBUG 1
// Kana's kitchen {{{
#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define LOOP(k)                                                                \
  for (i64 ngtkana_is_a_genius = 0; ngtkana_is_a_genius < (i64)k;              \
       ngtkana_is_a_genius++)

using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;

template <class T, class U> using pair = std::pair<U, T>;
template <class T> using diag_pair = std::pair<T, T>;
template <class... Args> using tuple = std::tuple<Args...>;
template <class T> using vec = std::vector<T>;
template <class T> using numr = std::numeric_limits<T>;

#ifdef NGTKANA
#include <debug.hpp>
#else
#define DEBUG(...) (void)0
#endif
/*}}}*/
auto cmx = [](auto &x, auto y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
};
int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  std::cout << std::setprecision(15) << std::fixed;

  usize n, k;
  std::cin >> n >> k;
  k--;
  vec<i64> pos, neg;
  usize zero = 0;
  for (usize i = 0; i < n; i++) {
    i64 x;
    std::cin >> x;
    if (0 < x)
      pos.push_back(x);
    if (x < 0)
      neg.push_back(-x);
    if (x == 0)
      zero++;
  }
  std::sort(ALL(pos));
  std::sort(ALL(neg));

  auto ans = [&]() -> i64 {
    usize base0 = pos.size() * neg.size();
    if (k < base0) {
      auto count_ge = [&](i64 X) {
        i64 ans = 0;
        for (i64 x : pos) {
          // ceil(X/x) <= y
          ans += neg.end() - std::lower_bound(ALL(neg), (X + x - 1) / x);
        }
        return ans;
      };
      i64 l = 0, r = pos.back() * neg.back() + 1;
      while (1 < r - l) {
        i64 c = (l + r) / 2;
        (k + 1 <= count_ge(c) ? l : r) = c;
      }
      return -l;
    }
    k -= base0;

    usize base1 = (zero * (zero - 1) / 2 + zero * (pos.size() + neg.size()));
    if (k < base1)
      return 0;
    k -= base1;

    auto count_le = [&](i64 X) {
      i64 ans = 0;
      for (auto &&v : {pos, neg}) {
        for (i64 x : v) {
          // y <= floor(X/x);
          ans += std::upper_bound(ALL(v), X / x) - v.begin();
        }
        for (i64 x : v) {
          ans -= x * x <= X;
        }
      }
      assert(ans % 2 == 0);
      ans /= 2;
      return ans;
    };
    i64 l = 0, r = std::max(pos.empty() ? 0ll : pos.back() * pos.back(),
                            neg.empty() ? 0ll : neg.back() * neg.back()) +
                   1;
    while (1 < r - l) {
      i64 c = (l + r) / 2;
      (k + 1 <= count_le(c) ? r : l) = c;
    }
    return r;
  }();

  std::cout << ans << '\n';
}