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

#include <algorithm>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;

#define EPS 1e-8
typedef complex<double> P;
typedef vector<P> G;

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

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

bool intersectLS(const L &l, const L &s) {
  return cross(l[1] - l[0], s[0] - l[0]) * // s[0] is left of l
             cross(l[1] - l[0], s[1] - l[0]) <
         EPS; // s[1] is right of l
}

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]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > +EPS)
    return +1;
  if (cross(b, c) < -EPS)
    return -1;
  if (dot(b, c) < -EPS)
    return +2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

bool notleft(P a, P b, P c) { return (ccw(a, b, c) != +1); }

bool isIntoG(const G &g, const P &p) {
  size_t sz = g.size();
  for (size_t i = 0; i < sz; i++) {
    if (notleft(p, g[i], g[(i + 1) % sz]))
      return false;
  }
  return true;
}

bool isfar(G &g, P &p) {
  for (int i = 0; i < g.size(); i++)
    if (abs(g[i] - p) < EPS)
      return false;

  return true;
}

#define CURR(P, i) P[i]
#define NEXT(P, i) P[(i + 1) % P.size()]

bool ConvexCut(G &g, L &l, vector<G> &ret) {
  int sp, inp = 0;
  for (sp = 0; sp < g.size(); sp++)
    if (intersectLS(l, L(g[sp], g[(sp + 1) % g.size()])))
      break;

  if (sp == g.size())
    return false;

  ret.resize(2);

  P xp = crosspoint(l, L(g[sp], g[(sp + 1) % g.size()]));
  sp++;

  for (int i = sp; i < sp + g.size(); i++) {
    if (isfar(ret[inp], g[i % g.size()]))
      ret[inp].push_back(g[i % g.size()]);
    if (intersectLS(l, L(g[i % g.size()], g[(i + 1) % g.size()]))) {
      P tx = crosspoint(l, L(g[i % g.size()], g[(i + 1) % g.size()]));
      if (abs(tx - xp) < EPS)
        continue;

      xp = tx;
      for (int j = 0; j < 2; j++) {
        if (isfar(ret[j], xp))
          ret[j].push_back(xp);
      }

      inp = (inp + 1) % 2;
    }
  }

  return true;
}

L trans(P a, P b) {
  P med = (a + b);
  med = P(med.real() / 2, med.imag() / 2);
  P hoge = (a - b);
  hoge *= P(0, 1);

  return L(med + hoge * P(1000, 0), med - hoge * P(1000, 0));
}

double Area(G &g) {
  double ret = 0;
  for (int i = 0; i < g.size(); i++)
    ret += cross(CURR(g, i), NEXT(g, i)) / 2;

  return ret;
}

int main() {
  cout << setiosflags(ios::fixed) << setprecision(7);

  int N, M;
  while (cin >> N >> M, (N || M)) {
    G g, pts;
    for (int i = 0; i < N; i++) {
      double x, y;
      cin >> x >> y;
      g.push_back(P(x, y));
    }
    for (int i = 0; i < M; i++) {
      double x, y;
      cin >> x >> y;
      pts.push_back(P(x, y));
    }

    for (int i = 0; i < M; i++) {
      G f = g;
      for (int j = 0; j < M; j++) {
        if (i == j)
          continue;
        L divide = trans(pts[i], pts[j]);
        vector<G> cut;
        if (!ConvexCut(f, divide, cut))
          continue;
        if (isIntoG(cut[0], pts[i]))
          f = cut[0];
        else
          f = cut[1];
      }

      cout << Area(f) << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;

#define EPS 1e-8
typedef complex<double> P;
typedef vector<P> G;

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

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

bool intersectLS(const L &l, const L &s) {
  return cross(l[1] - l[0], s[0] - l[0]) * // s[0] is left of l
             cross(l[1] - l[0], s[1] - l[0]) <
         EPS; // s[1] is right of l
}

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]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > +EPS)
    return +1;
  if (cross(b, c) < -EPS)
    return -1;
  if (dot(b, c) < -EPS)
    return +2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

bool notleft(P a, P b, P c) { return (ccw(a, b, c) != +1); }

bool isIntoG(const G &g, const P &p) {
  size_t sz = g.size();
  for (size_t i = 0; i < sz; i++) {
    if (notleft(p, g[i], g[(i + 1) % sz]))
      return false;
  }
  return true;
}

bool isfar(G &g, P &p) {
  for (int i = 0; i < g.size(); i++)
    if (abs(g[i] - p) < EPS)
      return false;

  return true;
}

#define CURR(P, i) P[i]
#define NEXT(P, i) P[(i + 1) % P.size()]

bool ConvexCut(G &g, L &l, vector<G> &ret) {
  int sp, inp = 0;
  for (sp = 0; sp < g.size(); sp++)
    if (intersectLS(l, L(g[sp], g[(sp + 1) % g.size()])))
      break;

  if (sp == g.size())
    return false;

  ret.resize(2);

  P xp = crosspoint(l, L(g[sp], g[(sp + 1) % g.size()]));
  sp++;

  for (int i = sp; i < sp + g.size(); i++) {
    if (isfar(ret[inp], g[i % g.size()]))
      ret[inp].push_back(g[i % g.size()]);
    if (intersectLS(l, L(g[i % g.size()], g[(i + 1) % g.size()]))) {
      P tx = crosspoint(l, L(g[i % g.size()], g[(i + 1) % g.size()]));
      if (abs(tx - xp) < EPS)
        continue;

      xp = tx;
      for (int j = 0; j < 2; j++) {
        if (isfar(ret[j], xp))
          ret[j].push_back(xp);
      }

      inp = (inp + 1) % 2;
    }
  }

  return true;
}

L trans(P a, P b) {
  P med = (a + b);
  med = P(med.real() / 2, med.imag() / 2);
  P hoge = (a - b);
  hoge *= P(0, 1);

  return L(med + hoge * P(1000, 0), med - hoge * P(1000, 0));
}

double Area(G &g) {
  double ret = 0;
  for (int i = 0; i < g.size(); i++)
    ret += cross(CURR(g, i), NEXT(g, i)) / 2;

  return ret;
}

int main() {
  cout << setiosflags(ios::fixed) << setprecision(7);

  int N, M;
  while (cin >> N >> M, (N || M)) {
    cin >> N >> M;
    G g, pts;
    for (int i = 0; i < N; i++) {
      double x, y;
      cin >> x >> y;
      g.push_back(P(x, y));
    }
    for (int i = 0; i < M; i++) {
      double x, y;
      cin >> x >> y;
      pts.push_back(P(x, y));
    }

    for (int i = 0; i < M; i++) {
      G f = g;
      for (int j = 0; j < M; j++) {
        if (i == j)
          continue;
        L divide = trans(pts[i], pts[j]);
        vector<G> cut;
        if (!ConvexCut(f, divide, cut))
          continue;
        if (isIntoG(cut[0], pts[i]))
          f = cut[0];
        else
          f = cut[1];
      }

      cout << Area(f) << endl;
    }
  }
}