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

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

// ---------- lib ----------
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;
  }
};
struct Line {
  Point p1, p2;
};

long double norm(const Point &a) { return a.px * a.px + a.py * a.py; }
long double dot(const Point &a, const Point &b) {
  return a.px * b.px + a.py * b.py;
}
long double abs(const Point &a) { return sqrtl(norm(a)); }
long double crs(const Point &a, const Point &b) {
  return a.px * b.py - a.py * b.px;
}
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;
}
long double dst(const Point &a, const Point &b) { return abs(b - a); }
Point prj(const Line &a, const Point &b) {
  return a.p1 + (a.p2 - a.p1) * dot(b - a.p1, a.p2 - a.p1) / norm(a.p2 - a.p1);
}
long double dst(const Line &a, const Point &b) {
  return abs(crs(a.p2 - a.p1, b - a.p1) / abs(a.p2 - a.p1));
}
// ---------- end ----------

int n, X[100000], Y[100000];
Point G[400000];
int dy[4] = {-1, 0, 1, 0}, dx[4] = {0, 1, 0, -1};
vector<Point> T, U;

int main() {
  cin >> n;
  X[0] = 0;
  Y[0] = 0;
  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    X[i] = X[a] + dx[b];
    Y[i] = Y[a] + dy[b];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++) {
        G[i * 4 + j * 2 + k] = Point(X[i] + j, Y[i] + k);
      }
  }
  sort(G, G + n * 4);
  T.push_back(G[0]);
  for (int i = 1; i < n * 4; i++) {
    if (G[i] != G[i - 1])
      T.push_back(G[i]);
  }
  U = convex_hull(T);
  long double maxn = 1e12;
  //---shakutorization---
  int pos1 = 0, pos2 = 0, pos3 = 0;
  for (int i = 0; i < U.size(); i++) {
    Line W = Line{U[i], U[(i + 1) % U.size()]};
    long double maxy = 0, minx = 1e12, maxx = -1e12;
    if (i == 0) {
      for (int j = 0; j < U.size(); j++) {
        long double DST = dst(W, U[j]);
        if (maxy < DST) {
          maxy = DST;
          pos1 = j;
        }
        Point PP = prj(W, U[j]);
        long double DST2 = dst(U[i], PP);
        if ((PP < U[i]) == (W.p1 < W.p2))
          DST2 *= -1;
        if (maxx < DST2) {
          maxx = DST2;
          pos2 = j;
        }
        if (minx > DST2) {
          minx = DST2;
          pos3 = j;
        }
      }
    } else {
      while (true) {
        long double DST = dst(W, U[pos1]);
        if (maxy > DST) {
          pos1 = (pos1 + U.size() - 1) % U.size();
          break;
        }
        maxy = DST;
        pos1 = (pos1 + 1) % U.size();
      }
      while (true) {
        Point PP = prj(W, U[pos2]);
        long double DST = dst(U[i], PP);
        if ((PP < U[i]) == (W.p1 < W.p2))
          DST *= -1;
        if (maxx > DST) {
          pos2 = (pos2 + U.size() - 1) % U.size();
          break;
        }
        maxx = DST;
        pos2 = (pos2 + 1) % U.size();
      }
      while (true) {
        Point PP = prj(W, U[pos3]);
        long double DST = dst(U[i], PP);
        if ((PP < U[i]) == (W.p1 < W.p2))
          DST *= -1;
        if (minx < DST) {
          pos3 = (pos3 + U.size() - 1) % U.size();
          break;
        }
        minx = DST;
        pos3 = (pos3 + 1) % U.size();
      }
    }
    maxn = min(maxn, maxy * (maxx - minx));
  }
  printf("%.20Lf\\n", maxn);
  return 0;
}

Error: TLE

Fixed submission:

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

// ---------- lib ----------
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;
  }
};
struct Line {
  Point p1, p2;
};

long double norm(const Point &a) { return a.px * a.px + a.py * a.py; }
long double dot(const Point &a, const Point &b) {
  return a.px * b.px + a.py * b.py;
}
long double abs(const Point &a) { return sqrtl(norm(a)); }
long double crs(const Point &a, const Point &b) {
  return a.px * b.py - a.py * b.px;
}
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;
}
long double dst(const Point &a, const Point &b) { return abs(b - a); }
Point prj(const Line &a, const Point &b) {
  return a.p1 + (a.p2 - a.p1) * dot(b - a.p1, a.p2 - a.p1) / norm(a.p2 - a.p1);
}
long double dst(const Line &a, const Point &b) {
  return abs(crs(a.p2 - a.p1, b - a.p1) / abs(a.p2 - a.p1));
}
// ---------- end ----------

int n, X[100000], Y[100000];
Point G[400000];
int dy[4] = {-1, 0, 1, 0}, dx[4] = {0, 1, 0, -1};
vector<Point> T, U;

int main() {
  cin >> n;
  X[0] = 0;
  Y[0] = 0;
  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    X[i] = X[a] + dx[b];
    Y[i] = Y[a] + dy[b];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++) {
        G[i * 4 + j * 2 + k] = Point(X[i] + j, Y[i] + k);
      }
  }
  sort(G, G + n * 4);
  T.push_back(G[0]);
  for (int i = 1; i < n * 4; i++) {
    if (G[i] != G[i - 1])
      T.push_back(G[i]);
  }
  U = convex_hull(T);
  long double maxn = 1e12;
  for (int i = 0; i < U.size(); i++) {
    Line W = Line{U[i], U[(i + 1) % U.size()]};
    long double maxy = 0, minx = 1e12, maxx = -1e12;
    for (int j = 0; j < U.size(); j++) {
      long double DST = dst(W, U[j]);
      maxy = max(maxy, DST);
      Point PP = prj(W, U[j]);
      long double DST2 = dst(U[i], PP);
      if (PP < U[i])
        DST2 *= -1;
      maxx = max(maxx, DST2);
      minx = min(minx, DST2);
    }
    maxn = min(maxn, maxy * (maxx - minx));
  }
  printf("%.20Lf\\n", maxn);
  return 0;
}