Problem p03585 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
const double eps = 1e-12;
int a[40005], b[40005], c[40005];
struct Line {
  double k, b;
  double y;
};
Line xLine[40005];
Line yLine[40005];
double t[40005];
int bit[40005];

void initBit(int n) {
  for (int i = 1; i <= n; i++)
    bit[i] = 0;
}

void change(int p, int v, int n) {
  while (p <= n) {
    bit[p] += v;
    p += p & -p;
  }
}

double abs(double u) { return u > 0 ? u : -u; }

int ask(int p) {
  int res = 0;
  while (p != 0) {
    res += bit[p];
    p -= p & -p;
  }
  return res;
}

int preWork(int n) {
  std::sort(t + 1, t + 1 + n);
  int p = 1, size = 0;
  while (p <= n) {
    int np = p;
    while (np + 1 <= n && abs(t[np + 1] - t[p]) <= eps)
      np++;
    t[++size] = t[p];
    p = np + 1;
  }
  return size;
}

int getId(double u, int n) {
  int L = 1, R = n;
  int res = -1;
  while (L <= R) {
    int M = (L + R) / 2;
    if (t[M] <= (u + eps)) {
      res = M;
      L = M + 1;
    } else
      R = M - 1;
  }
  return res;
}

long long getCnt(double x, Line line[], int n) {
  for (int i = 1; i <= n; i++) {
    line[i].y = line[i].k * x + line[i].b;
    t[i] = line[i].y;
    // printf("y = %.6f ",t[i]);
  }
  // printf("\n");
  int upper = preWork(n);
  initBit(upper);
  long long cnt = 0;
  for (int i = 1; i <= n; i++) {
    int u = getId(line[i].y, upper);
    cnt += (long long)ask(u);
    change(u, 1, upper);
  }
  initBit(upper);
  for (int i = n; i >= 1; i--) {
    int u = getId(line[i].y, upper);
    cnt += (long long)ask(upper) - (long long)ask(u - 1);
    change(u, 1, upper);
  }
  return cnt;
}

double getAnswer(Line line[], int n) {
  long long all = n * (n - 1);
  double L = -(1e10 + 7), R = 1e10 + 7;
  double res = -1;
  for (int i = 0; i < 500; i++) {
    double M = (L + R) / 2;
    long long cnt = getCnt(M, line, n);
    if (cnt * 2ll >= all) {
      res = M;
      R = M - eps;
    } else
      L = M + eps;
  }
  return res;
}

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    xLine[i].k = (double)(-a[i]) / (double)b[i];
    xLine[i].b = (double)c[i] / (double)b[i];
    // printf("k = %.3f, b = %.3f\n",xLine[i].k,xLine[i].b);
    yLine[i].k = (double)(-b[i]) / (double)a[i];
    yLine[i].b = (double)c[i] / (double)a[i];
  }
  std::sort(xLine + 1, xLine + 1 + n,
            [&](Line &u, Line &v) { return u.k < v.k; });
  std::sort(yLine + 1, yLine + 1 + n,
            [&](Line &u, Line &v) { return u.k < v.k; });
  // yLine sort...
  printf("%.12f %.12f\n", getAnswer(xLine, n), getAnswer(yLine, n));
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
const double eps = 1e-12;
int a[40005], b[40005], c[40005];
struct Line {
  double k, b;
  double y;
};
Line xLine[40005];
Line yLine[40005];
double t[40005];
int bit[40005];

void initBit(int n) {
  for (int i = 1; i <= n; i++)
    bit[i] = 0;
}

void change(int p, int v, int n) {
  while (p <= n) {
    bit[p] += v;
    p += p & -p;
  }
}

double abs(double u) { return u > 0 ? u : -u; }

int ask(int p) {
  int res = 0;
  while (p != 0) {
    res += bit[p];
    p -= p & -p;
  }
  return res;
}

int preWork(int n) {
  std::sort(t + 1, t + 1 + n);
  int p = 1, size = 0;
  while (p <= n) {
    int np = p;
    while (np + 1 <= n && abs(t[np + 1] - t[p]) <= eps)
      np++;
    t[++size] = t[p];
    p = np + 1;
  }
  return size;
}

int getId(double u, int n) {
  int L = 1, R = n;
  int res = -1;
  while (L <= R) {
    int M = (L + R) / 2;
    if (t[M] <= (u + eps)) {
      res = M;
      L = M + 1;
    } else
      R = M - 1;
  }
  return res;
}

long long getCnt(double x, Line line[], int n) {
  for (int i = 1; i <= n; i++) {
    line[i].y = line[i].k * x + line[i].b;
    t[i] = line[i].y;
    // printf("y = %.6f ",t[i]);
  }
  // printf("\n");
  int upper = preWork(n);
  initBit(upper);
  long long cnt = 0;
  for (int i = 1; i <= n; i++) {
    int u = getId(line[i].y, upper);
    cnt += (long long)ask(u);
    change(u, 1, upper);
  }
  initBit(upper);
  for (int i = n; i >= 1; i--) {
    int u = getId(line[i].y, upper);
    cnt += (long long)ask(upper) - (long long)ask(u - 1);
    change(u, 1, upper);
  }
  return cnt;
}

double getAnswer(Line line[], int n) {
  long long all = n * (n - 1);
  double L = -(1e10 + 7), R = 1e10 + 7;
  double res = -1;
  for (int i = 0; i < 100; i++) {
    double M = (L + R) / 2;
    long long cnt = getCnt(M, line, n);
    if (cnt * 2ll >= all) {
      res = M;
      R = M - eps;
    } else
      L = M + eps;
  }
  return res;
}

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    xLine[i].k = (double)(-a[i]) / (double)b[i];
    xLine[i].b = (double)c[i] / (double)b[i];
    // printf("k = %.3f, b = %.3f\n",xLine[i].k,xLine[i].b);
    yLine[i].k = (double)(-b[i]) / (double)a[i];
    yLine[i].b = (double)c[i] / (double)a[i];
  }
  std::sort(xLine + 1, xLine + 1 + n,
            [&](Line &u, Line &v) { return u.k < v.k; });
  std::sort(yLine + 1, yLine + 1 + n,
            [&](Line &u, Line &v) { return u.k < v.k; });
  // yLine sort...
  printf("%.12f %.12f\n", getAnswer(xLine, n), getAnswer(yLine, n));
  return 0;
}