Problem p02774 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

struct init_ {
  init_() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  }
} init_;

template <class C>
using iodef_rng_t =
    typename enable_if<decltype(declval<C>().begin(), true_type{})::value &&
                       !is_same<C, string>::value>::type;
template <class C, class = iodef_rng_t<C>>
istream &operator>>(istream &in, C &c) {
  for (auto &v : c) {
    in >> v;
  }
  return in;
}
template <class C, class = iodef_rng_t<C>>
ostream &operator<<(ostream &out, const C &c) {
  int i = 0;
  for (const auto &v : c) {
    if (i++) {
      out << ' ';
    }
    out << v;
  }
  return out;
}
template <size_t N, class T, class R>
using when_last =
    typename enable_if<N == tuple_size<remove_reference_t<T>>::value - 1,
                       R>::type;
template <size_t N, class T, class R>
using when_init =
    typename enable_if<N != tuple_size<remove_reference_t<T>>::value - 1,
                       R>::type;
template <size_t N = 0, class T>
auto operator>>(istream &in, T &&t) -> when_last<N, T, istream &> {
  return in >> get<N>(t);
}
template <size_t N = 0, class T>
auto operator>>(istream &in, T &&t) -> when_init<N, T, istream &> {
  return operator>><N + 1>(in >> get<N>(t), forward<T>(t));
}
template <size_t N = 0, class T>
auto operator<<(ostream &out, const T &t) -> when_last<N, T, ostream &> {
  return out << get<N>(t);
}
template <size_t N = 0, class T>
auto operator<<(ostream &out, const T &t) -> when_init<N, T, ostream &> {
  return operator<< <N + 1>(out << get<N>(t) << ' ', t);
}

#ifdef LOCAL
template <class T> void trace_(const char *s, const T &v) {
  cerr << s << "=" << v;
}
template <class T, class... Ts>
void trace_(const char *s, const T &v, const Ts &...vs) {
  for (; *s != ','; ++s) {
    cerr << *s;
  }
  cerr << "=" << v << ",";
  trace_(++s, vs...);
}
#define TRACE(...)                                                             \
  (cerr << "\033[2m\033[33m", trace_(#__VA_ARGS__, __VA_ARGS__),               \
   cerr << "\033[0m\n")
#else
#define TRACE(...)
#endif

template <class Int, class Pred>
Int bsearch(Int first, Int last, Pred p) noexcept {
  size_t len = last - first, half;
  Int mid;
  while (len > 0) {
    half = len >> 1;
    mid = first + half;
    if (p(mid)) {
      first = mid + 1;
      len = len - half - 1;
    } else {
      len = half;
    }
  }
  return first;
}

int main() {
  int64_t n, k;
  cin >> n >> k;
  vector<int64_t> p, m, z;
  for (int i = 0; i < n; i++) {
    int64_t x;
    cin >> x;
    if (x == 0)
      z.push_back(x);
    else if (x > 0)
      p.push_back(x);
    else
      m.push_back(-x);
  }
  int64_t num_m_ans = p.size() * m.size();
  int64_t num_z_ans =
      z.size() * (z.size() - 1) / 2 + z.size() * (m.size() + p.size());
  TRACE(num_m_ans, num_z_ans);
  int64_t ans;
  if (k <= num_m_ans) {
    sort(p.begin(), p.end());
    sort(m.begin(), m.end());
    ans = -bsearch(1L, p.back() * m.back() + 1, [&](int64_t x) {
      int64_t lowerx = 0;
      for (size_t i = 0; i < p.size(); i++) {
        lowerx +=
            bsearch(0UL, m.size(), [&](size_t j) { return m[j] <= x / p[i]; });
      }
      TRACE(x, lowerx);
      return lowerx < num_m_ans - k + 1;
    });
  } else if (k <= num_m_ans + num_z_ans) {
    ans = 0;
  } else {
    sort(p.begin(), p.end());
    sort(m.begin(), m.end());
    int64_t max_abs = max(p.back(), m.back());
    ans = bsearch(1L, max_abs * max_abs + 1, [&](int64_t x) {
      int64_t lowerx = 0;
      for (size_t i = 1; i < p.size(); i++) {
        lowerx += bsearch(0UL, i, [&](size_t j) { return p[j] <= x / p[i]; });
      }
      for (size_t i = 1; i < m.size(); i++) {
        lowerx += bsearch(0UL, i, [&](size_t j) { return m[j] <= x / m[i]; });
      }
      TRACE(x, lowerx);
      return lowerx < k - num_m_ans - num_z_ans;
    });
  }
  cout << ans << '\n';
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

struct init_ {
  init_() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  }
} init_;

template <class C>
using iodef_rng_t =
    typename enable_if<decltype(declval<C>().begin(), true_type{})::value &&
                       !is_same<C, string>::value>::type;
template <class C, class = iodef_rng_t<C>>
istream &operator>>(istream &in, C &c) {
  for (auto &v : c) {
    in >> v;
  }
  return in;
}
template <class C, class = iodef_rng_t<C>>
ostream &operator<<(ostream &out, const C &c) {
  int i = 0;
  for (const auto &v : c) {
    if (i++) {
      out << ' ';
    }
    out << v;
  }
  return out;
}
template <size_t N, class T, class R>
using when_last =
    typename enable_if<N == tuple_size<remove_reference_t<T>>::value - 1,
                       R>::type;
template <size_t N, class T, class R>
using when_init =
    typename enable_if<N != tuple_size<remove_reference_t<T>>::value - 1,
                       R>::type;
template <size_t N = 0, class T>
auto operator>>(istream &in, T &&t) -> when_last<N, T, istream &> {
  return in >> get<N>(t);
}
template <size_t N = 0, class T>
auto operator>>(istream &in, T &&t) -> when_init<N, T, istream &> {
  return operator>><N + 1>(in >> get<N>(t), forward<T>(t));
}
template <size_t N = 0, class T>
auto operator<<(ostream &out, const T &t) -> when_last<N, T, ostream &> {
  return out << get<N>(t);
}
template <size_t N = 0, class T>
auto operator<<(ostream &out, const T &t) -> when_init<N, T, ostream &> {
  return operator<< <N + 1>(out << get<N>(t) << ' ', t);
}

#ifdef LOCAL
template <class T> void trace_(const char *s, const T &v) {
  cerr << s << "=" << v;
}
template <class T, class... Ts>
void trace_(const char *s, const T &v, const Ts &...vs) {
  for (; *s != ','; ++s) {
    cerr << *s;
  }
  cerr << "=" << v << ",";
  trace_(++s, vs...);
}
#define TRACE(...)                                                             \
  (cerr << "\033[2m\033[33m", trace_(#__VA_ARGS__, __VA_ARGS__),               \
   cerr << "\033[0m\n")
#else
#define TRACE(...)
#endif

template <class Int, class Pred>
Int bsearch(Int first, Int last, Pred p) noexcept {
  size_t len = last - first, half;
  Int mid;
  while (len > 0) {
    half = len >> 1;
    mid = first + half;
    if (p(mid)) {
      first = mid + 1;
      len = len - half - 1;
    } else {
      len = half;
    }
  }
  return first;
}

int main() {
  int64_t n, k;
  cin >> n >> k;
  vector<int64_t> p, m, z;
  for (int i = 0; i < n; i++) {
    int64_t x;
    cin >> x;
    if (x == 0)
      z.push_back(x);
    else if (x > 0)
      p.push_back(x);
    else
      m.push_back(-x);
  }
  int64_t num_m_ans = p.size() * m.size();
  int64_t num_z_ans =
      z.size() * (z.size() - 1) / 2 + z.size() * (m.size() + p.size());
  TRACE(num_m_ans, num_z_ans);
  int64_t ans;
  if (k <= num_m_ans) {
    sort(p.begin(), p.end());
    sort(m.begin(), m.end());
    ans = -bsearch(1L, p.back() * m.back() + 1, [&](int64_t x) {
      int64_t lowerx = 0;
      for (size_t i = 0; i < p.size(); i++) {
        lowerx +=
            bsearch(0UL, m.size(), [&](size_t j) { return m[j] <= x / p[i]; });
      }
      TRACE(x, lowerx);
      return lowerx < num_m_ans - k + 1;
    });
  } else if (k <= num_m_ans + num_z_ans) {
    ans = 0;
  } else {
    sort(p.begin(), p.end());
    sort(m.begin(), m.end());
    int64_t max_abs = m.empty()   ? p.back()
                      : p.empty() ? m.back()
                                  : max(p.back(), m.back());
    ans = bsearch(1L, max_abs * max_abs + 1, [&](int64_t x) {
      int64_t lowerx = 0;
      for (size_t i = 1; i < p.size(); i++) {
        lowerx += bsearch(0UL, i, [&](size_t j) { return p[j] <= x / p[i]; });
      }
      for (size_t i = 1; i < m.size(); i++) {
        lowerx += bsearch(0UL, i, [&](size_t j) { return m[j] <= x / m[i]; });
      }
      TRACE(x, lowerx);
      return lowerx < k - num_m_ans - num_z_ans;
    });
  }
  cout << ans << '\n';
}