Problem p02774 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
  int N;
  ll K;
  cin >> N >> K;
  ll A;
  vector<ll> B;
  vector<ll> C;
  ll z = 0;
  for (int i = 0; i < N; i++) {
    cin >> A;
    if (A == 0)
      z++;
    else if (A < 0)
      B.push_back(A);
    else
      C.push_back(A);
  }
  ll nb = B.size();
  ll nc = C.size();
  ll f0 = nb * nc;
  ll f1 = f0 + z * (nb + nc) + (z * (z - 1)) / 2;
  sort(B.begin(), B.end());
  if (K <= f0) {
    sort(C.begin(), C.end(), greater<ll>());
    ll l = -1e18 - 1ll;
    ll r = 0;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      ll sum = 0;
      for (int i = 0; i < nb; i++) {
        int j = 0;
        while (j < nc && B[i] * C[j] <= m)
          j++;
        if (j == 0)
          break;
        //        cout << i << " " << j << " " << m << endl;
        sum += j;
      }
      // cout << sum << " " << m << "\n";
      if (sum < K)
        l = m;
      else
        r = m;
    }
    cout << r << "\n";
  } else if (K <= f1) {
    cout << "0\n";
  } else {
    sort(C.begin(), C.end());
    ll l = 0;
    ll r = 1e18 + 1ll;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      ll sum = f1;
      int j = nb - 1;
      for (int i = 0; i < nb - 1; i++) {
        while (j >= 0 && B[i] * B[j] <= m)
          j--;
        sum += min((int)nb - j - 1, (int)nb - i - 1);
      }

      j = 0;
      for (int i = nc - 1; i >= 1; i--) {
        while (j < nc && C[i] * C[j] <= m)
          j++;
        sum += min(i, j);
      }
      // cout << sum << " " << m << "\n";
      if (sum < K)
        l = m;
      else
        r = m;
    }
    cout << r << "\n";
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
  int N;
  ll K;
  cin >> N >> K;
  ll A;
  vector<ll> B;
  vector<ll> C;
  ll z = 0;
  for (int i = 0; i < N; i++) {
    cin >> A;
    if (A == 0)
      z++;
    else if (A < 0)
      B.push_back(A);
    else
      C.push_back(A);
  }
  ll nb = B.size();
  ll nc = C.size();
  ll f0 = nb * nc;
  ll f1 = f0 + z * (nb + nc) + (z * (z - 1)) / 2;
  sort(B.begin(), B.end());
  if (K <= f0) {
    sort(C.begin(), C.end(), greater<ll>());
    ll l = -1e18 - 1ll;
    ll r = 0;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      ll sum = 0;
      int j = nb;
      for (int i = 0; i < nc; i++) {
        j = upper_bound(B.begin(), B.begin() + j,
                        m / C[i] - (m % C[i] ? 1 : 0)) -
            B.begin();
        //        while (j < nc && B[i] * C[j] <= m)
        //          j++;
        if (j == 0)
          break;
        //        cout << i << " " << j << " " << m << endl;
        sum += j;
      }
      // cout << sum << " " << m << "\n";
      if (sum < K)
        l = m;
      else
        r = m;
    }
    cout << r << "\n";
  } else if (K <= f1) {
    cout << "0\n";
  } else {
    sort(C.begin(), C.end());
    ll l = 0;
    ll r = 1e18 + 1ll;
    while (r - l > 1) {
      ll m = (l + r) / 2;
      ll sum = f1;
      int j = nb - 1;
      for (int i = 0; i < nb - 1; i++) {
        while (j >= 0 && B[i] * B[j] <= m)
          j--;
        sum += min((int)nb - j - 1, (int)nb - i - 1);
      }

      j = 0;
      for (int i = nc - 1; i >= 1; i--) {
        while (j < nc && C[i] * C[j] <= m)
          j++;
        sum += min(i, j);
      }
      // cout << sum << " " << m << "\n";
      if (sum < K)
        l = m;
      else
        r = m;
    }
    cout << r << "\n";
  }
  return 0;
}