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

#include <bits/stdc++.h>
using namespace std;
typedef double dbl;
#define double long double
typedef complex<double> P;
typedef vector<P> G;
#define REP(i, n) for (int i = 0; i < n; i++)
double eps = 1e-11;
double EPS = eps;

bool eq(double a, double b) { return fabs(a - b) < eps; }

double cross(P a, P b) { return imag(conj(a) * b); }
double dot(P a, P b) { return real(conj(a) * b); }

vector<P> ps1, ps2;
//??´???
struct L : public vector<P> {
  L(P a, P b) {
    push_back(a);
    push_back(b);
  }
};
int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // a ??? b ??§???????¨??????????????????? b ??? c(???)
  if (cross(b, c) < 0)
    return -1; // a ??? b ??§????¨??????????????????? b ??? c(???)
  if (dot(b, c) < 0)
    return +2; // a???b??§????????????a??????????¶???????b???c(c--a--b)
  if (norm(b) < norm(c))
    return -2; // a???b??§????????????b???c(a--b--c)
  return 0;    // a???b??§????????????b???c(????????? b == c)
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0];
  return m[0] + B / A * (m[1] - m[0]);
}

// ???????§???¢???????????????????§???¢???????????´?????§????????????
//???????????´?????????????????´?????????????????´?????????????????¨?????????????????¨?????????????????????????????¨????????????????????????
#define curr(P, i) P[(i) % P.size()]
#define next(P, i) P[(i + 1) % P.size()]
#define prev(P, i) P[(i + P.size() - 1) % P.size()]
G convex_cut(const G &poly, const L &l) {
  G Q;
  for (int i = 0; i < poly.size(); ++i) {
    P A = curr(poly, i), B = next(poly, i);
    if (ccw(l[0], l[1], A) != -1)
      Q.push_back(A);
    if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0)
      Q.push_back(crosspoint(L(A, B), l));
  }
  return Q;
}

// ????´?????§???¢?????¢??????"2???"????±??????? O(n)
double area2(const G &poly) {
  double A = 0;
  REP(i, poly.size()) A += cross(curr(poly, i), next(poly, i));
  return abs(A);
}

vector<double> ux;

P in() {
  double x, y;
  cin >> x >> y;

  return P(x, y);
}
pair<double, double> seg(const vector<P> &ps, double x) {
  double mi = 1e9, ma = -1e9;
  auto reflesh = [&mi, &ma](double y) {
    mi = min(mi, y);
    ma = max(ma, y);
  };
  for (int i = 0; i < ps.size(); i++) {
    P a = ps[i];
    P b = ps[(i + 1) % ps.size()];
    if (a.real() > b.real())
      swap(a, b);
    if (eq(a.real(), x))
      reflesh(a.imag());
    if (eq(b.real(), x))
      reflesh(b.imag());
    if (a.real() + eps < x and x < b.real() - eps) {
      reflesh(a.imag() +
              (x - a.real()) * (b.imag() - a.imag()) / (b.real() - a.real()));
    }
  }
  if (ma < mi)
    return {0.0, 0.0};
  return {mi, ma};
}

double S(double l, double r) {
  if (r <= l)
    return 0;
  G g1 = convex_cut(ps1, L(P(l, 0), P(l, -1)));
  G g2 = convex_cut(g1, L(P(r, 0), P(r, +1)));

  return area2(g2) / 2;
}

double Vf(double z) {
  auto p = seg(ps2, z);
  return S(p.first, p.second);
}

double Vs(double l, double r) {
  return (r - l) / 6 * (Vf(l) + 4 * Vf((l + r) / 2) + Vf(r));
}

double V(double l, double r, int k = 6) {
  if (l >= r)
    return 0;
  double m = (l + r) / 2;
  double a = Vs(l, m);
  double b = Vs(m, r);
  double c = Vs(l, r);
  if ((k <= 0) and eq(a + b, c)) {
    return c;
  } else {
    return V(l, m, k - 1) + V(m, r, k - 1);
  }
}

int main() {
  int m, n;
  while (cin >> m >> n && m) {

    ps1.clear();
    ps2.clear();
    ux.clear();
    for (int i = 0; i < m; i++) {
      ps1.push_back(in());
      ux.push_back(ps1.back().real());
    }

    vector<double> uz;
    for (int i = 0; i < n; i++) {
      ps2.push_back(in());
      ps2.back() = P(ps2.back().imag(), ps2.back().real());
      uz.push_back(ps2.back().real());
    }

    sort(uz.begin(), uz.end());
    sort(ux.begin(), ux.end());
    double vans = 0;
    // for( auto z : uz ) cout << z << " "; cout << endl;
    // for( auto x : ux ) cout << x << " "; cout << endl;
    for (int i = 0; i + 1 < uz.size(); i++)
      if (uz[i] != uz[i + 1])
        vans += V(uz[i], uz[i + 1]);
    printf("%.8lf\\n", (dbl)vans);
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef double dbl;
#define double long double
typedef complex<double> P;
typedef vector<P> G;
#define REP(i, n) for (int i = 0; i < n; i++)
double eps = 1e-11;
double EPS = eps;

bool eq(double a, double b) { return fabs(a - b) < eps; }

double cross(P a, P b) { return imag(conj(a) * b); }
double dot(P a, P b) { return real(conj(a) * b); }

vector<P> ps1, ps2;
//??´???
struct L : public vector<P> {
  L(P a, P b) {
    push_back(a);
    push_back(b);
  }
};
int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // a ??? b ??§???????¨??????????????????? b ??? c(???)
  if (cross(b, c) < 0)
    return -1; // a ??? b ??§????¨??????????????????? b ??? c(???)
  if (dot(b, c) < 0)
    return +2; // a???b??§????????????a??????????¶???????b???c(c--a--b)
  if (norm(b) < norm(c))
    return -2; // a???b??§????????????b???c(a--b--c)
  return 0;    // a???b??§????????????b???c(????????? b == c)
}

P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0];
  return m[0] + B / A * (m[1] - m[0]);
}

// ???????§???¢???????????????????§???¢???????????´?????§????????????
//???????????´?????????????????´?????????????????´?????????????????¨?????????????????¨?????????????????????????????¨????????????????????????
#define curr(P, i) P[(i) % P.size()]
#define next(P, i) P[(i + 1) % P.size()]
#define prev(P, i) P[(i + P.size() - 1) % P.size()]
G convex_cut(const G &poly, const L &l) {
  G Q;
  for (int i = 0; i < poly.size(); ++i) {
    P A = curr(poly, i), B = next(poly, i);
    if (ccw(l[0], l[1], A) != -1)
      Q.push_back(A);
    if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0)
      Q.push_back(crosspoint(L(A, B), l));
  }
  return Q;
}

// ????´?????§???¢?????¢??????"2???"????±??????? O(n)
double area2(const G &poly) {
  double A = 0;
  REP(i, poly.size()) A += cross(curr(poly, i), next(poly, i));
  return abs(A);
}

vector<double> ux;

P in() {
  double x, y;
  cin >> x >> y;

  return P(x, y);
}
pair<double, double> seg(const vector<P> &ps, double x) {
  double mi = 1e9, ma = -1e9;
  auto reflesh = [&mi, &ma](double y) {
    mi = min(mi, y);
    ma = max(ma, y);
  };
  for (int i = 0; i < ps.size(); i++) {
    P a = ps[i];
    P b = ps[(i + 1) % ps.size()];
    if (a.real() > b.real())
      swap(a, b);
    if (eq(a.real(), x))
      reflesh(a.imag());
    if (eq(b.real(), x))
      reflesh(b.imag());
    if (a.real() + eps < x and x < b.real() - eps) {
      reflesh(a.imag() +
              (x - a.real()) * (b.imag() - a.imag()) / (b.real() - a.real()));
    }
  }
  if (ma < mi)
    return {0.0, 0.0};
  return {mi, ma};
}

double S(double l, double r) {
  if (r <= l)
    return 0;
  G g1 = convex_cut(ps1, L(P(l, 0), P(l, -1)));
  G g2 = convex_cut(g1, L(P(r, 0), P(r, +1)));

  return area2(g2) / 2;
}

double Vf(double z) {
  auto p = seg(ps2, z);
  return S(p.first, p.second);
}

double Vs(double l, double r) {
  return (r - l) / 6 * (Vf(l) + 4 * Vf((l + r) / 2) + Vf(r));
}

double V(double l, double r, int k = 7) {
  if (l >= r)
    return 0;
  double m = (l + r) / 2;
  double a = Vs(l, m);
  double b = Vs(m, r);
  double c = Vs(l, r);
  if ((k <= 0) and eq(a + b, c)) {
    return c;
  } else {
    return V(l, m, k - 1) + V(m, r, k - 1);
  }
}

int main() {
  int m, n;
  while (cin >> m >> n && m) {

    ps1.clear();
    ps2.clear();
    ux.clear();
    for (int i = 0; i < m; i++) {
      ps1.push_back(in());
      ux.push_back(ps1.back().real());
    }

    vector<double> uz;
    for (int i = 0; i < n; i++) {
      ps2.push_back(in());
      ps2.back() = P(ps2.back().imag(), ps2.back().real());
      uz.push_back(ps2.back().real());
    }

    sort(uz.begin(), uz.end());
    sort(ux.begin(), ux.end());
    double vans = 0;
    // for( auto z : uz ) cout << z << " "; cout << endl;
    // for( auto x : ux ) cout << x << " "; cout << endl;
    for (int i = 0; i + 1 < uz.size(); i++)
      if (uz[i] != uz[i + 1])
        vans += V(uz[i], uz[i + 1]);
    printf("%.8lf\\n", (dbl)vans);
  }
}