Problem p02774 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define _ << " " <<
#define all(X) (X).begin(), (X).end()
#define len(X) (X).size()
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define Tiii tuple<int, int, int>
#define Tlll tuple<ll, ll, ll>

ll count_pos(ll val, vector<ll> a, vector<ll> d) {
  ll cnt = 0;
  for (int i = 0; i < a.size(); i++) {
    ll bd = val / a[i];
    ll l = -1, r = a.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (a[m] <= bd)
        l = m;
      else
        r = m;
    }
    cnt += l + 1;
    if (i <= l)
      cnt--;
    // cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  for (int i = 0; i < d.size(); i++) {
    ll bd = val / d[i];
    ll l = -1, r = d.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (d[m] <= bd)
        l = m;
      else
        r = m;
    }
    cnt += l + 1;
    if (i <= l)
      cnt--;
    // cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  return cnt / 2;
}

ll count_neg(ll val, vector<ll> b, vector<ll> c) {
  ll cnt = 0;
  for (int i = 0; i < c.size(); i++) {
    ll bd = val / c[i] + bool(val % c[i]);
    ll l = -1, r = b.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (b[m] < bd)
        l = m;
      else
        r = m;
    }
    cnt += b.size() - r;
    cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  return cnt;
}

int main() {
  ll n, k, neg = 0, zero = 0;
  cin >> n >> k;
  vector<ll> a(n), b, c, d;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    neg += (a[i] < 0);
    zero += (a[i] == 0);
    if (a[i] > 0)
      b.push_back(a[i]);
    if (a[i] < 0) {
      c.push_back(a[i]);
      d.push_back(-a[i]);
    }
  }

  sort(all(a));
  sort(all(b));
  sort(all(c));
  sort(all(d));

  neg = neg * (n - zero - neg);
  zero = zero * (zero - 1) / 2 + zero * (n - zero);
  cerr << neg _ zero << endl;

  if (neg >= k) {
    ll l = -2e18, r = 0;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (count_neg(m, b, c) >= k)
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  } else if (neg + zero >= k) {
    cout << 0 << endl;
  } else {
    k -= neg + zero;
    ll l = 0, r = 2e18;
    // cerr << k << endl;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      // cerr << m _ count_pos(m, b, d) << endl;
      if (count_pos(m, b, d) >= k)
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  }
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define _ << " " <<
#define all(X) (X).begin(), (X).end()
#define len(X) (X).size()
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define Tiii tuple<int, int, int>
#define Tlll tuple<ll, ll, ll>

ll count_pos(ll val, vector<ll> a, vector<ll> d) {
  ll cnt = 0;
  for (int i = 0; i < a.size(); i++) {
    ll bd = val / a[i];
    ll l = -1, r = a.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (a[m] <= bd)
        l = m;
      else
        r = m;
    }
    cnt += l + 1;
    if (i <= l)
      cnt--;
    // cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  for (int i = 0; i < d.size(); i++) {
    ll bd = val / d[i];
    ll l = -1, r = d.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (d[m] <= bd)
        l = m;
      else
        r = m;
    }
    cnt += l + 1;
    if (i <= l)
      cnt--;
    // cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  return cnt / 2;
}

ll count_neg(ll val, vector<ll> b, vector<ll> c) {
  ll cnt = 0;
  for (int i = 0; i < c.size(); i++) {
    ll bd = val / c[i] + bool(val % c[i]);
    ll l = -1, r = b.size();
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (b[m] < bd)
        l = m;
      else
        r = m;
    }
    cnt += b.size() - r;
    // cerr << val _ bd _ i _ l _ cnt << endl;
    //
  }
  return cnt;
}

int main() {
  ll n, k, neg = 0, zero = 0;
  cin >> n >> k;
  vector<ll> a(n), b, c, d;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    neg += (a[i] < 0);
    zero += (a[i] == 0);
    if (a[i] > 0)
      b.push_back(a[i]);
    if (a[i] < 0) {
      c.push_back(a[i]);
      d.push_back(-a[i]);
    }
  }

  sort(all(a));
  sort(all(b));
  sort(all(c));
  sort(all(d));

  neg = neg * (n - zero - neg);
  zero = zero * (zero - 1) / 2 + zero * (n - zero);
  cerr << neg _ zero << endl;

  if (neg >= k) {
    ll l = -2e18, r = 0;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      if (count_neg(m, b, c) >= k)
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  } else if (neg + zero >= k) {
    cout << 0 << endl;
  } else {
    k -= neg + zero;
    ll l = 0, r = 2e18;
    // cerr << k << endl;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      // cerr << m _ count_pos(m, b, d) << endl;
      if (count_pos(m, b, d) >= k)
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  }
}