Problem p02774 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i, n) for (ll i = 0; i < (n); ++i)

ll binary_search(ll lo, ll hi, function<bool(ll)> is_ok, bool maximize) {
  while (lo < hi) {
    if (maximize) {
      const ll mid = (lo + hi + 1) / 2;
      if (is_ok(mid)) {
        lo = mid;
      } else {
        hi = mid - 1;
      }
    } else {
      ll mid = (lo + hi) / 2;
      if (mid == hi) {
        mid--;
      }
      if (is_ok(mid)) {
        hi = mid;
      } else {
        lo = mid + 1;
      }
    }
  }
  return lo;
}

ll ceildiv(ll x, ll y) {
  if (x >= 0 && y > 0) {
    return (x + y - 1) / y;
  } else if (x >= 0 && y < 0) {
    return -x / abs(y);
  } else if (x < 0 && y > 0) {
    return -abs(x) / y;
  } else {
    assert(x < 0 && y < 0);
    return (abs(x) + abs(y) - 1) / abs(y);
  }
}

ll floordiv(ll x, ll y) {
  if (x >= 0 && y > 0) {
    return x / y;
  } else if (x >= 0 && y < 0) {
    return -(x + abs(y) - 1) / abs(y);
  } else if (x < 0 && y > 0) {
    return -(abs(x) + y - 1) / y;
  } else {
    assert(x < 0 && y > 0);
    return abs(x) / abs(y);
  }
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  REP(i, n) { cin >> a.at(i); }
  sort(a.begin(), a.end());
  const ll maxval = ll(1e18) + 1;
  const ll minval = -maxval;

  ll ans = ::binary_search(
      minval, maxval,
      [&](ll x) {
        ll count = 0;
        REP(i, n) {
          ll tmp = 0;
          if (a.at(i) == 0) {
            if (x > 0) {
              tmp = n - 1 - i;
            }
          } else if (a.at(i) > 0) {
            const ll y = ceildiv(x, a.at(i));
            const auto it_start = a.begin() + i + 1;
            tmp = lower_bound(it_start, a.end(), y) - it_start;
          } else {
            assert(a.at(i) < 0);
            const ll y = floordiv(x, a.at(i));
            const auto it_start = a.begin() + i + 1;
            tmp = a.end() - upper_bound(it_start, a.end(), y);
          }
          count += tmp;
        }
        return count < k;
      },
      true);
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i, n) for (ll i = 0; i < (n); ++i)

ll binary_search(ll lo, ll hi, function<bool(ll)> is_ok, bool maximize) {
  while (lo < hi) {
    if (maximize) {
      const ll mid = (lo + hi + 1) / 2;
      if (is_ok(mid)) {
        lo = mid;
      } else {
        hi = mid - 1;
      }
    } else {
      ll mid = (lo + hi) / 2;
      if (mid == hi) {
        mid--;
      }
      if (is_ok(mid)) {
        hi = mid;
      } else {
        lo = mid + 1;
      }
    }
  }
  return lo;
}

ll ceildiv(ll x, ll y) {
  if (x >= 0 && y > 0) {
    return (x + y - 1) / y;
  } else if (x >= 0 && y < 0) {
    return -x / abs(y);
  } else if (x < 0 && y > 0) {
    return -abs(x) / y;
  } else {
    assert(x < 0 && y < 0);
    return (abs(x) + abs(y) - 1) / abs(y);
  }
}

ll floordiv(ll x, ll y) {
  if (x >= 0 && y > 0) {
    return x / y;
  } else if (x >= 0 && y < 0) {
    return -(x + abs(y) - 1) / abs(y);
  } else if (x < 0 && y > 0) {
    return -(abs(x) + y - 1) / y;
  } else {
    assert(x < 0 && y < 0);
    return abs(x) / abs(y);
  }
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  REP(i, n) { cin >> a.at(i); }
  sort(a.begin(), a.end());
  const ll maxval = ll(1e18) + 1;
  const ll minval = -maxval;

  ll ans = ::binary_search(
      minval, maxval,
      [&](ll x) {
        ll count = 0;
        REP(i, n) {
          ll tmp = 0;
          if (a.at(i) == 0) {
            if (x > 0) {
              tmp = n - 1 - i;
            }
          } else if (a.at(i) > 0) {
            const ll y = ceildiv(x, a.at(i));
            const auto it_start = a.begin() + i + 1;
            tmp = lower_bound(it_start, a.end(), y) - it_start;
          } else {
            assert(a.at(i) < 0);
            const ll y = floordiv(x, a.at(i));
            const auto it_start = a.begin() + i + 1;
            tmp = a.end() - upper_bound(it_start, a.end(), y);
          }
          count += tmp;
        }
        return count < k;
      },
      true);
  cout << ans << endl;
  return 0;
}