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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

// ------ Class ------ //
class Point {
public:
  long double px, py;
  Point() : px(0), py(0){};
  Point(long double px_, long double py_) : px(px_), py(py_){};
  bool operator==(const Point &p) const { return px == p.px && py == p.py; }
  bool operator!=(const Point &p) const { return px != p.px || py != p.py; }
  bool operator<(const Point &p) const {
    return px < p.px ? true : (px == p.px && py < p.py);
  }
  bool operator>(const Point &p) const {
    return px > p.px ? true : (px == p.px && py > p.py);
  }
  bool operator<=(const Point &p) const { return !(Point(px, py) > p); }
  bool operator>=(const Point &p) const { return !(Point(px, py) < p); }
  Point operator+(const Point &p) const { return Point(px + p.px, py + p.py); }
  Point operator-(const Point &p) const { return Point(px - p.px, py - p.py); }
  Point operator/(long double d) const { return Point(px / d, py / d); }
  friend Point operator*(const Point p, long double d) {
    return Point(p.px * d, p.py * d);
  }
  friend Point operator*(long double d, const Point &p) { return p * d; }
  Point &operator+=(const Point &p1) {
    px += p1.px, py += p1.py;
    return *this;
  }
  Point &operator-=(const Point &p1) {
    px -= p1.px, py -= p1.py;
    return *this;
  }
  Point &operator*=(long double d) {
    px *= d, py *= d;
    return *this;
  }
  Point &operator/=(long double d) {
    px /= d, py /= d;
    return *this;
  }
};

// ------ Functions ------ //
long double norm(const Point &a) { return a.px * a.px + a.py * a.py; }
long double abs(const Point &a) { return sqrtl(norm(a)); }
long double arg(const Point &a) { return atan2l(a.py, a.px); }
long double dot(const Point &a, const Point &b) {
  return a.px * b.px + a.py * b.py;
}
long double crs(const Point &a, const Point &b) {
  return a.px * b.py - a.py * b.px;
}
Point pol(long double r, long double d) {
  return Point(cosl(d) * r, sinl(d) * r);
}
int ccw(const Point &p0, const Point &p1, const Point &p2) {
  Point a = p1 - p0, b = p2 - p0;
  if (crs(a, b) > 1e-10)
    return 1;
  if (crs(a, b) < -1e-10)
    return -1;
  if (dot(a, b) < -1e-10)
    return 2;
  if (norm(a) < norm(b))
    return -2;
  return 0;
}
vector<Point> convex_hull(vector<Point> v) {
  if (v.size() < 3)
    return v;
  sort(v.begin(), v.end());
  vector<Point> u = {v[0], v[1]}, l = {v[v.size() - 1], v[v.size() - 2]};
  for (int i = 2; i < v.size(); i++) {
    for (int n = u.size(); n >= 2 && ccw(u[n - 2], u[n - 1], v[i]) >= 0; n--)
      u.pop_back();
    u.push_back(v[i]);
  }
  for (int i = v.size() - 3; i >= 0; i--) {
    for (int n = l.size(); n >= 2 && ccw(l[n - 2], l[n - 1], v[i]) >= 0; n--)
      l.pop_back();
    l.push_back(v[i]);
  }
  reverse(l.begin(), l.end());
  for (int i = u.size() - 2; i >= 1; i--)
    l.push_back(u[i]);
  return l;
}

// ------ Main ------ //
int n, m;
vector<Point> v1, v2, v3, v4;
bool ok(int i) {
  int u = (i + 1) % v3.size();
  for (int j = 0; j < v4.size(); j++) {
    if (abs(ccw(v3[i], v3[u], v4[j])) != 1) {
      return false;
    }
  }
  for (int j = 0; j < v3.size(); j++) {
    if (i == j || u == j)
      continue;
    for (int k = 0; k < v4.size(); k++) {
      if (ccw(v3[i], v3[u], v3[j]) == ccw(v3[i], v3[u], v4[k])) {
        return false;
      }
    }
  }
  for (int j = 0; j < v4.size(); j++) {
    for (int k = j + 1; k < v4.size(); k++) {
      if (ccw(v3[i], v3[u], v4[j]) != ccw(v3[i], v3[u], v4[k])) {
        return false;
      }
    }
  }
  return true;
}
int main() {
  while (cin >> n >> m, n + m) {
    v1.resize(n), v2.resize(m);
    for (int i = 0; i < n; i++)
      cin >> v1[i].px >> v1[i].py;
    for (int i = 0; i < m; i++)
      cin >> v2[i].px >> v2[i].py;
    v3 = convex_hull(v1), v4 = convex_hull(v2);
    int x = 0;
    if (v3.size() == 1 && v4.size() == 1)
      x = 1;
    if (v3.size() > 1) {
      int w = ccw(v3[0], v3[1], v4[0]);
      if (abs(w) == 2) {
        int f = 1;
        for (int i = 1; i < v4.size(); i++) {
          if (ccw(v3[0], v3[1], v4[i]) != w)
            f = 0;
        }
        if (f)
          x = 1;
      }
    }
    if (v4.size() > 1) {
      int w = ccw(v4[0], v4[1], v3[0]);
      if (abs(w) == 2) {
        int f = 1;
        for (int i = 1; i < v3.size(); i++) {
          if (ccw(v4[0], v4[1], v3[i]) != w)
            f = 0;
        }
        if (f)
          x = 1;
      }
    }
    for (int i = 0; i < v3.size(); i++) {
      if (ok(i))
        x = 1;
    }
    swap(v3, v4);
    for (int i = 0; i < v4.size(); i++) {
      if (ok(i))
        x = 1;
    }
    cout << (x ? "YES" : "NO") << endl;
  }
}

Error: TLE

Fixed submission:

#ifndef ___STD_GEOMETRY
#define ___STD_GEOMETRY

#include <cmath>

#define EPS 1e-13L

#endif

#ifndef ___Class_Point
#define ___Class_Point

class Point {
public:
  // ------ Variable ------ //

  long double x, y;

  // ------ Constructor ------ //

  Point() : x(0), y(0) {}

  explicit Point(long double x, long double y) : x(x), y(y) {}

  // ------ Operator ------ //

  friend bool operator==(Point &p1, Point &p2) {
    return p1.x == p2.x && p1.y == p2.y;
  }
  friend bool operator!=(Point &p1, Point &p2) {
    return p1.x != p2.x || p1.y != p2.y;
  }
};

long double distance(const Point &p1, const Point &p2) {
  return sqrtl((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}

#endif

#ifndef ___Class_Vector
#define ___Class_Vector

class Vector {
public:
  // ------ Variable ------ //

  long double x, y;

  // ------ Constructor ------ //

  Vector() : x(0), y(0) {}

  explicit Vector(long double x, long double y) : x(x), y(y) {}

  explicit Vector(Point p1, Point p2) : x(p2.x - p1.x), y(p2.y - p1.y) {}

  explicit Vector(long double sx, long double tx, long double sy,
                  long double ty)
      : x(tx - sx), y(ty - sy) {}

  // ------ Operator ------ //

  Vector operator+() const { return Vector(+x, +y); }
  Vector operator-() const { return Vector(-x, -y); }

  Vector &operator+=(const Vector &v) {
    x += v.x;
    y += v.y;
    return *this;
  }
  Vector &operator-=(const Vector &v) {
    x -= v.x;
    y -= v.y;
    return *this;
  }

  friend bool operator==(const Vector &v1, const Vector &v2) {
    return -EPS < v1.x - v2.x && v1.x - v2.x < EPS && -EPS < v1.y - v2.y &&
           v1.y - v2.y < EPS;
  }
  friend bool operator!=(const Vector &v1, const Vector &v2) {
    return !(v1 == v2);
  }

  friend Vector operator+(const Vector &v1, const Vector &v2) {
    return Vector(v1.x + v2.x, v1.y + v2.y);
  }
  friend Vector operator-(const Vector &v1, const Vector &v2) {
    return Vector(v1.x - v2.x, v1.y - v2.y);
  }

  friend Vector operator*(double d, const Vector &v) {
    return Vector(d * v.x, d * v.y);
  }
  friend Vector operator*(const Vector &v, double d) {
    return Vector(d * v.x, d * v.y);
  }
  friend Vector operator/(const Vector &v, double d) {
    return Vector(v.x / d, v.y / d);
  }

  // ------ Function ------ //

  long double norm() { return x * x + y * y; }

  long double abs() { return sqrtl(x * x + y * y); }

  long double angle() { return atan2l(y, x); }
};

long double angle(const Vector &v1, const Vector &v2) {
  long double A = atan2l(v2.y, v2.x) - atan2l(v1.y, v1.x);

  if (180.0L - EPS < A && A < 180.0L + EPS) {
    return 180.0L;
  }

  if (-180.0L - EPS < A && A < -180.0L + EPS) {
    return 180.0L;
  }

  if (A > 180.0L - EPS) {
    return A - 360.0L;
  }

  if (A < -180.0L + EPS) {
    return A + 360.0L;
  }

  return A;
}

long double norm(const Vector &v1) { return v1.x * v1.x + v1.y * v1.y; }

long double abs(const Vector &v1) { return sqrt(norm(v1)); }

long double cross(const Vector &v1, const Vector &v2) {
  return v1.x * v2.y - v1.y * v2.x;
}

long double dot(const Vector &v1, const Vector &v2) {
  return v1.x * v2.x + v1.y * v2.y;
}

long double distance(const Vector &v1, const Vector &v2) {
  return sqrtl((v2.x - v1.x) * (v2.x - v1.x) + (v2.y - v1.y) * (v2.y - v1.y));
}

#endif

bool Triangle_Inside(Vector Tp1, Vector Tp2, Vector Tp3,
                     Vector p) // Triangle is Counter-Clockwise
{
  bool ok1 = !(angle(p - Tp1, Tp2 - Tp1) < 0 ^
               angle(Tp2 - Tp1, p - Tp1) < angle(Tp2 - Tp1, Tp3 - Tp1));
  bool ok2 = !(angle(p - Tp2, Tp3 - Tp2) < 0 ^
               angle(Tp3 - Tp2, p - Tp2) < angle(Tp3 - Tp2, Tp1 - Tp2));
  bool ok3 = !(angle(p - Tp3, Tp1 - Tp3) < 0 ^
               angle(Tp1 - Tp3, p - Tp3) < angle(Tp1 - Tp3, Tp2 - Tp3));

  return ok1 && ok2 && ok3;
}

bool On_Segment(Vector Sp1, Vector Sp2, Vector p) {
  return (Sp1 + Sp2) / 2 == p;
}

int Counter_Clockwise(Vector p1, Vector p2, Vector p3) {
  Vector a = p2 - p1;
  Vector b = p3 - p1;

  if (cross(a, b) > EPS) {
    return 1;
  }
  if (cross(a, b) < -EPS) {
    return -1;
  }

  if (dot(a, b) < -EPS) {
    return 2;
  }

  if (a.norm() < b.norm()) {
    return -2;
  }

  return 0;
}

bool Intersection(Vector p1, Vector p2, Vector p3, Vector p4) {
  int ok1 = Counter_Clockwise(p1, p2, p3) * Counter_Clockwise(p1, p2, p4);
  int ok2 = Counter_Clockwise(p3, p4, p1) * Counter_Clockwise(p3, p4, p2);

  return ok1 <= 0 && ok2 <= 0;
}

#include <iostream>
#include <vector>

using namespace std;

int main() {
  int N, M, X, Y;

  while (true) {
    cin >> N >> M;

    if (N == 0 && M == 0) {
      break;
    }

    vector<Vector> W(N);
    vector<Vector> B(M);

    for (int i = 0; i < N; i++) {
      cin >> X >> Y;
      W[i] = Vector(X, Y);
    }
    for (int i = 0; i < M; i++) {
      cin >> X >> Y;
      B[i] = Vector(X, Y);
    }

    bool ok = true;

    for (int i = 0; i < N; i++) {
      for (int j = i + 1; j < N; j++) {
        for (int k = 0; k < M; k++) {
          if (On_Segment(W[i], W[j], B[k]) == true) {
            ok = false;
          }
        }
      }
    }

    for (int i = 0; i < M; i++) {
      for (int j = i + 1; j < M; j++) {
        for (int k = 0; k < N; k++) {
          if (On_Segment(B[i], B[j], W[k]) == true) {
            ok = false;
          }
        }
      }
    }

    if (ok == true) {
      if (N > 2 || M > 2) {
        for (int i = 0; i < N; i++) {
          for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {
              for (int l = 0; l < M; l++) {
                if (Triangle_Inside(W[i], W[j], W[k], B[l])) {
                  ok = false;
                  goto Exit;
                }
              }
            }
          }
        }

        for (int i = 0; i < M; i++) {
          for (int j = i + 1; j < M; j++) {
            for (int k = j + 1; k < M; k++) {
              for (int l = 0; l < N; l++) {
                if (Triangle_Inside(B[i], B[j], B[k], W[l])) {
                  ok = false;
                  goto Exit;
                }
              }
            }
          }
        }
      } else if (N == 2 && M == 2) {
        ok = (Intersection(W[0], W[1], B[0], B[1]) == true ? false : true);
      }
    }

  Exit:;

    cout << (ok == true ? "YES" : "NO") << endl;
  }

  return 0;
}