Problem p03585 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

class BinaryIndexedTree {
  vector<int64_t> container;

public:
  BinaryIndexedTree(size_t size) : container(size + 1) {
    fill(container.begin(), container.end(), 0);
  }
  void add(size_t i, int64_t v) {
    size_t idx = i + 1;
    while (idx < container.size()) {
      container[idx] += v;
      idx += idx & -idx;
    }
  }
  int64_t find(size_t i) {
    size_t idx = i;

    int64_t result = 0;
    while (idx != 0) {
      result = container[idx] + result;
      idx -= idx & -idx;
    }
    return result;
  }
};

using L = tuple<int, int, int>;
using P = tuple<double, size_t>;

const double INF = 1e9;

int main() {
  cout << fixed << setprecision(10);

  vector<L> ys;

  int n;
  cin >> n;
  const int half = ((n * (n - 1) / 2) + 1) / 2;
  rep(i, n) {
    int a, b, c;
    cin >> a >> b >> c;
    ys.push_back(make_tuple(a, b, c));
  }

  double result[2];
  rep(i, 2) {
    sort(ys.begin(), ys.end(), [](const L &lh, const L &rh) {
      int la, lb, ra, rb;
      tie(la, lb, ignore) = lh;
      tie(ra, rb, ignore) = rh;

      return -(double)la / lb > -(double)ra / rb;
    });

    double lb = -INF / 2, ub = INF / 2;
    while (ub - lb >= 1e-9) {
      const double mid = ub / 2 + lb / 2;

      vector<P> tmp;
      tmp.reserve(ys.size());
      rep(i, ys.size()) {
        int a, b, c;
        tie(a, b, c) = ys[i];
        tmp.push_back(make_tuple((c - a * mid) / b, i));
      }
      sort(tmp.begin(), tmp.end());

      int64_t intersection = 0;
      BinaryIndexedTree bit(tmp.size());
      rep(i, tmp.size()) {
        size_t j;
        tie(ignore, j) = tmp[i];
        intersection += bit.find(tmp.size()) - bit.find(j + 1);
        bit.add(j, 1);
      }

      (intersection >= half ? ub : lb) = mid;
    }
    result[i] = ub;

    for (L &l : ys) {
      swap(get<0>(l), get<1>(l));
    }
  }
  cout << result[0] << " " << result[1] << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

class BinaryIndexedTree {
  vector<int64_t> container;

public:
  BinaryIndexedTree(size_t size) : container(size + 1) {
    fill(container.begin(), container.end(), 0);
  }
  void add(size_t i, int64_t v) {
    size_t idx = i + 1;
    while (idx < container.size()) {
      container[idx] += v;
      idx += idx & -idx;
    }
  }
  int64_t find(size_t i) {
    size_t idx = i;

    int64_t result = 0;
    while (idx != 0) {
      result = container[idx] + result;
      idx -= idx & -idx;
    }
    return result;
  }
};

using L = tuple<int, int, int>;
using P = tuple<double, size_t>;

const double INF = 1e9;

int main() {
  cout << fixed << setprecision(10);

  vector<L> ys;

  int n;
  cin >> n;
  const int half = ((n * (n - 1) / 2) + 1) / 2;
  rep(i, n) {
    int a, b, c;
    cin >> a >> b >> c;
    ys.push_back(make_tuple(a, b, c));
  }

  double result[2];
  rep(i, 2) {
    sort(ys.begin(), ys.end(), [](const L &lh, const L &rh) {
      int la, lb, ra, rb;
      tie(la, lb, ignore) = lh;
      tie(ra, rb, ignore) = rh;

      return -(double)la / lb > -(double)ra / rb;
    });

    double lb = -INF, ub = INF;
    rep(i, 256) {
      const double mid = ub / 2 + lb / 2;

      vector<P> tmp;
      tmp.reserve(ys.size());
      rep(i, ys.size()) {
        int a, b, c;
        tie(a, b, c) = ys[i];
        tmp.push_back(make_tuple((c - a * mid) / b, i));
      }
      sort(tmp.begin(), tmp.end());

      int64_t intersection = 0;
      BinaryIndexedTree bit(tmp.size());
      rep(i, tmp.size()) {
        size_t j;
        tie(ignore, j) = tmp[i];
        intersection += bit.find(tmp.size()) - bit.find(j + 1);
        bit.add(j, 1);
      }

      (intersection >= half ? ub : lb) = mid;
    }
    result[i] = ub;

    for (L &l : ys) {
      swap(get<0>(l), get<1>(l));
    }
  }
  cout << result[0] << " " << result[1] << endl;

  return 0;
}