Problem p01609 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long double ld;
const ld eps = 1e-9;

vector<ld> quadraticEquation(ld a, ld b, ld c) {
  if (abs(a) < eps) {
    return {-c / b};
  } else {
    ld d = b * b - 4 * a * c;
    if (abs(d) < eps) {
      return {(-b + sqrt(d)) / (2 * a)};
    } else if (0 < d) {
      return {(-b + sqrt(d)) / (2 * a), (-b - sqrt(d)) / (2 * a)};
    } else {
      return {};
    }
  }
}

ld simpson(ld x0, ld x_max, function<ld(ld)> f) {
  ld a;
  const int n = 1e5;
  const ld dx = (x_max - x0) / n;
  a = f(x0);
  a += f(x0 + dx * n);
  int i;
  for (i = 1; i < n; i += 2) {
    a += 4.0 * f(x0 + dx * i);
  }
  for (i = 2; i < n; i += 2) {
    a += 2.0 * f(x0 + dx * i);
  }
  return a * dx / 3.0;
}

ld W, H, N;
ld a[55], p[55], q[55];

ld f(int i, ld x) { return a[i] * (x - p[i]) * (x - p[i]) + q[i]; }

bool inside(ld x, ld y) {
  if (x < -eps || W < x - eps)
    return false;
  if (y < -eps || H < y - eps)
    return false;
  return true;
}

ld solve() {
  vector<ld> es = {0, W};
  rep(i, N) {
    auto xs = quadraticEquation(a[i], -a[i] * 2 * p[i],
                                q[i] + a[i] * p[i] * p[i]); // on x axis
    for (ld x : xs)
      if (inside(x, f(i, x)))
        es.push_back(x);
    rep(j, i) {
      ld aa = a[i] - a[j];
      ld bb = -a[i] * 2 * p[i] - (-a[j] * 2 * p[j]);
      ld cc = (q[i] + a[i] * p[i] * p[i]) - (q[j] + a[j] * p[j] * p[j]);
      auto cs = quadraticEquation(aa, bb, cc);
      for (ld x : cs) {
        if (inside(x, f(i, x))) {
          es.push_back(x);
        }
      }
    }
  }
  sort(es.begin(), es.end());
  ld ans = 0;
  rep(i, es.size() - 1) {
    ld x1 = es[i], x2 = es[i + 1];
    ld m = (x1 + x2) / 2;
    int idx = -1;
    ld maxy = -1e9;
    rep(j, N) {
      if (maxy < f(j, m)) {
        maxy = f(j, m);
        idx = j;
      }
    }
    if (maxy > -eps) {
      ans += simpson(x1, x2, [&](ld x) {
        ld dy = a[idx] * 2 * (x - p[idx]);
        return sqrt(1 + dy * dy);
      });
    }
  }
  return ans;
}

int main() {
  while (cin >> W >> H >> N) {
    rep(i, N) cin >> a[i] >> p[i] >> q[i];
    printf("%.10lf\\n", (double)solve());
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long double ld;
const ld eps = 1e-9;

vector<ld> quadraticEquation(ld a, ld b, ld c) {
  if (abs(a) < eps) {
    return {-c / b};
  } else {
    ld d = b * b - 4 * a * c;
    if (abs(d) < eps) {
      return {(-b + sqrt(d)) / (2 * a)};
    } else if (0 < d) {
      return {(-b + sqrt(d)) / (2 * a), (-b - sqrt(d)) / (2 * a)};
    } else {
      return {};
    }
  }
}

ld simpson(ld x0, ld x_max, function<ld(ld)> f) {
  ld a;
  const int n = 1e6;
  const ld dx = (x_max - x0) / n;
  a = f(x0);
  a += f(x0 + dx * n);
  int i;
  for (i = 1; i < n; i += 2) {
    a += 4.0 * f(x0 + dx * i);
  }
  for (i = 2; i < n; i += 2) {
    a += 2.0 * f(x0 + dx * i);
  }
  return a * dx / 3.0;
}

ld W, H, N;
ld a[55], p[55], q[55];

ld f(int i, ld x) { return a[i] * (x - p[i]) * (x - p[i]) + q[i]; }

ld Df(int i, ld x) { return 2 * a[i] * (x - p[i]); }

bool inside(ld x, ld y) {
  if (x < -eps || W < x - eps)
    return false;
  if (y < -eps || H < y - eps)
    return false;
  return true;
}

ld solve() {
  vector<ld> es = {0, W};
  rep(i, N) {
    auto xs = quadraticEquation(a[i], -a[i] * 2 * p[i],
                                q[i] + a[i] * p[i] * p[i]); // on x axis
    for (ld x : xs)
      if (inside(x, f(i, x)))
        es.push_back(x);
    rep(j, i) {
      ld aa = a[i] - a[j];
      ld bb = -a[i] * 2 * p[i] - (-a[j] * 2 * p[j]);
      ld cc = (q[i] + a[i] * p[i] * p[i]) - (q[j] + a[j] * p[j] * p[j]);
      auto cs = quadraticEquation(aa, bb, cc);
      // cout << "solve " << endl;
      // cout << aa << ' ' << bb << ' ' << cc << endl;
      for (ld x : cs) {
        // cout << "x " << x << endl;
        if (inside(x, f(i, x))) {
          es.push_back(x);
        }
      }
    }
  }
  sort(es.begin(), es.end());
  // rep(i,es.size()){
  //     cout << ' ' << es[i];
  // }
  // cout << endl;
  ld ans = 0;
  rep(i, es.size() - 1) {
    ld x1 = es[i], x2 = es[i + 1];
    struct Cand {
      ld y, Dy, a;
      int id;
      bool operator<(const Cand &rhs) const {
        if (abs(y - rhs.y) > eps)
          return y < rhs.y;
        if (abs(Dy - rhs.Dy) > eps)
          return Dy < rhs.Dy;
        if (abs(a - rhs.a) > eps)
          return Dy < rhs.Dy;
        return id < rhs.id;
      }
    };
    Cand maxi = {-1e9, 0, 0, 0};
    rep(j, N) { maxi = max(maxi, Cand{f(j, x1), Df(j, x1), abs(a[j]), j}); }
    // cout << get<0>(maxi) << ' '
    //      << get<1>(maxi) << ' '
    //      << get<2>(maxi) << ' '
    //      << get<3>(maxi) << endl;
    if (maxi.y < -eps || ((abs(maxi.y) < eps && maxi.Dy < eps)))
      continue;
    // cout << "integral " << x1 << ' ' << x2 << ' ' << "f" << maxi.id << endl;
    ans += simpson(x1, x2, [&](ld x) {
      ld dy = Df(maxi.id, x);
      return sqrt(1 + dy * dy);
    });
  }
  return ans;
}

int main() {
  while (cin >> W >> H >> N) {
    rep(i, N) cin >> a[i] >> p[i] >> q[i];
    printf("%.10lf\\n", (double)solve());
  }
}