Problem p03585 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
typedef pair<long double, int> l_i;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
int N;
long double A[40050], B[40050], C[40050];
struct SegmentTree {
private:
  int n;
  vector<int> node;

public:
  SegmentTree() {
    int sz = 50000;
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1, INF);
    for (int i = 0; i < sz; i++)
      node[i + n - 1] = 0;
    for (int i = n - 2; i >= 0; i--)
      node[i] = min(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int x, int val) {
    x += (n - 1);
    node[x] = val;
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = (node[2 * x + 1] + node[2 * x + 2]);
    }
  }
  // hannkaikukann
  int getsum(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return node[k];

    int vl = getsum(a, b, 2 * k + 1, l, (l + r) / 2);
    int vr = getsum(a, b, 2 * k + 2, (l + r) / 2, r);
    return (vl + vr);
  }
};

long double solve() {
  vector<l_i> m(N);
  for (int i = 1; i <= N; i++) {
    m[i - 1] = {-A[i] / B[i], i};
  }
  sort(m.begin(), m.end());
  vector<int> inv(N + 1);
  for (int i = 0; i < N; i++) {
    inv[m[i].second] = i + 1;
    // cerr << i << " " << m[i].second << " " << m[i].first << endl;
  }
  long double ok = 1e30;
  long double ng = -1e30;
  for (int time = 0; time < 300; time++) {
    long double mid = (ok + ng) / 2.0;
    SegmentTree seg;
    vector<l_i> now(N);
    for (int i = 1; i <= N; i++) {
      now[i - 1] = {(A[i] * mid - C[i]) / (-B[i]), i};
    }
    sort(now.begin(), now.end());
    int inversion = 0;
    // cerr << "NOW: " << mid << endl;
    for (int i = 0; i < N; i++) {
      int nowindex = inv[now[i].second];
      // cerr << i << " " << nowindex << " " << now[i].first << endl;
      inversion += seg.getsum(0, nowindex);
      seg.update(nowindex, 1);
    }
    // cerr << mid << " " << inversion << endl;
    if (2 * inversion >= N * (N - 1) / 2)
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}

int main() {
  cout.precision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  for (int i = 1; i <= N; i++)
    cin >> A[i] >> B[i] >> C[i];
  long double ansx = solve();
  for (int i = 1; i <= N; i++)
    swap(A[i], B[i]);
  long double ansy = solve();
  cout << ansx << " " << ansy << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
typedef pair<long double, int> l_i;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
int N;
long double A[40050], B[40050], C[40050];
struct SegmentTree {
private:
  int n;
  vector<int> node;

public:
  SegmentTree() {
    int sz = 50000;
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1, INF);
    for (int i = 0; i < sz; i++)
      node[i + n - 1] = 0;
    for (int i = n - 2; i >= 0; i--)
      node[i] = min(node[2 * i + 1], node[2 * i + 2]);
  }

  void update(int x, int val) {
    x += (n - 1);
    node[x] = val;
    while (x > 0) {
      x = (x - 1) / 2;
      node[x] = (node[2 * x + 1] + node[2 * x + 2]);
    }
  }
  // hannkaikukann
  int getsum(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return node[k];

    int vl = getsum(a, b, 2 * k + 1, l, (l + r) / 2);
    int vr = getsum(a, b, 2 * k + 2, (l + r) / 2, r);
    return (vl + vr);
  }
};

long double solve() {
  vector<l_i> m(N);
  for (int i = 1; i <= N; i++) {
    m[i - 1] = {-A[i] / B[i], i};
  }
  sort(m.begin(), m.end());
  vector<int> inv(N + 1);
  for (int i = 0; i < N; i++) {
    inv[m[i].second] = i + 1;
    // cerr << i << " " << m[i].second << " " << m[i].first << endl;
  }
  long double ok = 1e18;
  long double ng = -1e18;
  for (int time = 0; time < 100; time++) {
    long double mid = (ok + ng) / 2.0;
    SegmentTree seg;
    vector<l_i> now(N);
    for (int i = 1; i <= N; i++) {
      now[i - 1] = {(A[i] * mid - C[i]) / (-B[i]), i};
    }
    sort(now.begin(), now.end());
    int inversion = 0;
    // cerr << "NOW: " << mid << endl;
    for (int i = 0; i < N; i++) {
      int nowindex = inv[now[i].second];
      // cerr << i << " " << nowindex << " " << now[i].first << endl;
      inversion += seg.getsum(0, nowindex);
      seg.update(nowindex, 1);
    }
    // cerr << mid << " " << inversion << endl;
    if (2 * inversion >= N * (N - 1) / 2)
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}

int main() {
  cout.precision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  for (int i = 1; i <= N; i++)
    cin >> A[i] >> B[i] >> C[i];
  long double ansx = solve();
  for (int i = 1; i <= N; i++)
    swap(A[i], B[i]);
  long double ansy = solve();
  cout << ansx << " " << ansy << endl;
  return 0;
}