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

#include <bits/stdc++.h>
// #define int long long

using namespace std;
using LL = long long;
using P = pair<int, int>;
using Tapris = tuple<int, int, int>;

#define FOR(i, a, n) for (int i = (int)(a); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)

#define pb(a) push_back(a)
#define all(x) (x).begin(), (x).end()

const int INF = (int)1e9;
const LL INFL = (LL)1e15;
const int MOD = 1e9 + 7;

int dy[] = {0, 0, 1, -1, 0};
int dx[] = {1, -1, 0, 0, 0};

typedef long double LD;
typedef complex<LD> Point;
typedef pair<Point, Point> Line;
typedef vector<Point> Polygon;
const LD EPS = 1e-10;
#define X real() // x座標を取得
#define Y imag() // y座標を取得
#define LE(n, m) ((n) < (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))
#define EQ(n, m) (abs((n) - (m)) < EPS)

// 内積 Dot(a, b) = |a||b|cosθ
LD Dot(Point a, Point b) { return (conj(a) * b).X; }

// 外積 Cross(a, b) = |a||b|sinθ
LD Cross(Point a, Point b) { return (conj(a) * b).Y; }

int CCW(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (Cross(b, c) > 0)
    return +1; // counter clockwise
  if (Cross(b, c) < 0)
    return -1; // clockwise
  if (Dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

//*********************************************
//          点と線(Point and Line)            *
//*********************************************

// 交差判定 (Isec) ****************************
// 点　 := 平面座標にある点
// 直線 := 点と点を通るどこまでも続く線
// 線分 := 点と点を結んでその両端で止まっている線

// 直線と点
bool IsecLP(Point a1, Point a2, Point b) { return abs(CCW(a1, a2, b)) != 1; }

// 直線と直線
bool IsecLL(Point a1, Point a2, Point b1, Point b2) {
  return !IsecLP(a2 - a1, b2 - b1, 0) || IsecLP(a1, b1, b2);
}

// 直線と線分
bool IsecLS(Point a1, Point a2, Point b1, Point b2) {
  return Cross(a2 - a1, b1 - a1) * Cross(a2 - a1, b2 - a1) < EPS;
}

// 線分と線分
bool IsecSS(Point a1, Point a2, Point b1, Point b2) {
  return CCW(a1, a2, b1) * CCW(a1, a2, b2) <= 0 &&
         CCW(b1, b2, a1) * CCW(b1, b2, a2) <= 0;
}

// 線分と点
bool IsecSP(Point a1, Point a2, Point b) { return !CCW(a1, a2, b); }

// ********************************************

// 距離 (Dist) ********************************
// 点pの直線aへの射影点を返す
Point Proj(Point a1, Point a2, Point p) {
  return a1 + Dot(a2 - a1, p - a1) / norm(a2 - a1) * (a2 - a1);
}

// 点pの直線aへの反射点を返す
Point Reflection(Point a1, Point a2, Point p) {
  return 2.0L * Proj(a1, a2, p) - p;
}

// 点と点
LD DistPP(Point a, Point b) { return abs(a - b); }

// 直線と点
LD DistLP(Point a1, Point a2, Point p) { return abs(Proj(a1, a2, p) - p); }

// 直線と直線
LD DistLL(Point a1, Point a2, Point b1, Point b2) {
  return IsecLL(a1, a2, b1, b2) ? 0 : DistLP(a1, a2, b1);
}

// 直線と線分
LD DistLS(Point a1, Point a2, Point b1, Point b2) {
  return IsecLS(a1, a2, b1, b2) ? 0
                                : min(DistLP(a1, a2, b1), DistLP(a1, a2, b2));
}

// 線分と点
LD DistSP(Point a1, Point a2, Point p) {
  if (Dot(a2 - a1, p - a1) < EPS)
    return abs(p - a1);
  if (Dot(a1 - a2, p - a2) < EPS)
    return abs(p - a2);
  return abs(Cross(a2 - a1, p - a1)) / abs(a2 - a1);
}

// 線分と線分
LD DistSS(Point a1, Point a2, Point b1, Point b2) {
  if (IsecSS(a1, a2, b1, b2))
    return 0;
  return min(min(DistSP(a1, a2, b1), DistSP(a1, a2, b2)),
             min(DistSP(b1, b2, a1), DistSP(b1, b2, a2)));
}

// ********************************************

// 2直線の交点 (CrossPoint) *******************
Point CrossPointLL(Point a1, Point a2, Point b1, Point b2) {
  LD d1 = Cross(b2 - b1, b1 - a1);
  LD d2 = Cross(b2 - b1, a2 - a1);
  if (EQ(d1, 0) && EQ(d2, 0))
    return a1;
  if (EQ(d2, 0))
    throw "not exist crosspoint";
  return a1 + d1 / d2 * (a2 - a1);
}
// ********************************************

//*********************************************
//             多角形(Polygon)                *
//*********************************************

namespace std {
bool operator<(Point a, Point b) { return a.X != b.X ? a.X < b.X : a.Y < b.Y; }
} // namespace std

// 多角形の面積 (PolygonErea) *****************
LD PolygonErea(Polygon p) {
  LD area = 0;
  int n = p.size();
  for (int i = 0; i < n; i++) {
    area += Cross(p[i], p[(i + 1) % n]);
  }
  return area / 2;
}
// ********************************************

// 凸性判定 (IsConvex) ************************
bool IsConvex(Polygon pol) {
  int n = pol.size();
  for (int i = 0; i < n; i++) {
    if (CCW(pol[i], pol[(i + 1) % n], pol[(i + 2) % n]) == -1)
      return false;
  }
  return true;
}
// ********************************************

// 多角形-点包含関係 (PolygonPointContainment)
int PolygonPointContainment(Polygon pol, Point p) {
  enum { OUT, ON, IN };
  bool in = false;
  int n = pol.size();
  for (int i = 0; i < n; i++) {
    Point a = pol[i] - p, b = pol[(i + 1) % n] - p;
    if (a.Y > b.Y)
      swap(a, b);
    if (a.Y <= 0 && 0 < b.Y && Cross(a, b) < 0)
      in = !in;
    if (Cross(a, b) == 0 && Dot(a, b) <= 0)
      return ON;
  }
  return in ? IN : OUT;
}
// ********************************************

//*********************************************
//          凸多角形(ConvexPolygon)           *
//*********************************************

// 凸包[θ<=180] (ConvexHull) *****************
Polygon ConvexHull(Polygon pol) {
  int n = pol.size(), k = 0;
  sort(pol.begin(), pol.end());
  Polygon ch(2 * n);
  for (int i = 0; i < n; ch[k++] = pol[i++])
    while (k >= 2 && CCW(ch[k - 2], ch[k - 1], pol[i]) == -1)
      --k;

  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = pol[i--])
    while (k >= t && CCW(ch[k - 2], ch[k - 1], pol[i]) == -1)
      --k;

  ch.resize(k - 1);
  return ch;
}
// ********************************************

// 凸包[θ<180] (ConvexHull2) *****************
Polygon ConvexHull2(Polygon pol) {
  int n = pol.size(), k = 0;
  sort(pol.begin(), pol.end());
  Polygon ch(2 * n);
  for (int i = 0; i < n; ch[k++] = pol[i++])
    while (k >= 2 && CCW(ch[k - 2], ch[k - 1], pol[i]) <= 0)
      --k;

  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = pol[i--])
    while (k >= t && CCW(ch[k - 2], ch[k - 1], pol[i]) <= 0)
      --k;

  ch.resize(k - 1);
  return ch;
}
// ********************************************

// 凸多角形の直径 (ConvexPolygonDiameter) *****
pair<int, int> ConvexPolygonDiameter(Polygon cpol) {
#define diff(P, i) (P[(i + 1) % P.size()] - P[i])
  int n = cpol.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(cpol[i]) > imag(cpol[is]))
      is = i;
    if (imag(cpol[i]) < imag(cpol[js]))
      js = i;
  }
  LD maxd = norm(cpol[is] - cpol[js]);

  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
    if (Cross(diff(cpol, i), diff(cpol, j)) >= 0)
      j = (j + 1) % n;
    else
      i = (i + 1) % n;
    if (norm(cpol[i] - cpol[j]) > maxd) {
      maxd = norm(cpol[i] - cpol[j]);
      maxi = i;
      maxj = j;
    }
  } while (i != is || j != js);
  return make_pair(maxi, maxj);
}
// ********************************************

// 凸多角形-点包含関係 (ConvexPolygonPointContainment)
int ConvexPolygonPointContainment(Polygon cpol, Point p) {
  enum { OUT, ON, IN };
  int n = cpol.size();
  Point g = (cpol[0] + cpol[n / 3] + cpol[2 * n / 3]) / 3.0L;
  int a = 0, b = n;
  while (a + 1 < b) {
    int c = (a + b) / 2;
    if (Cross(cpol[a] - g, cpol[c] - g) > 0) {
      if (Cross(cpol[a] - g, p - g) > 0 && Cross(cpol[c] - g, p - g) < 0)
        b = c;
      else
        a = c;
    } else {
      if (Cross(cpol[a] - g, p - g) < 0 && Cross(cpol[c] - g, p - g) > 0)
        a = c;
      else
        b = c;
    }
  }
  b %= n;
  if (Cross(cpol[a] - p, cpol[b] - p) < 0)
    return OUT;
  if (Cross(cpol[a] - p, cpol[b] - p) > 0)
    return IN;
  return ON;
}
// ********************************************

/************** using variables ***************/
Polygon p;
int n;
int q;
/**********************************************/

signed main() {
  cin >> n;
  REP(i, n) {
    LD xp, yp;
    cin >> xp >> yp;
    p.pb(Point(xp, yp));
  }
  pair<int, int> ans = ConvexPolygonDiameter(p);
  printf("%.9Lf\\n", DistPP(p[ans.first], p[ans.second]));
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// #define int long long

using namespace std;
using LL = long long;
using P = pair<int, int>;
using Tapris = tuple<int, int, int>;

#define FOR(i, a, n) for (int i = (int)(a); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)

#define pb(a) push_back(a)
#define all(x) (x).begin(), (x).end()

const int INF = (int)1e9;
const LL INFL = (LL)1e15;
const int MOD = 1e9 + 7;

int dy[] = {0, 0, 1, -1, 0};
int dx[] = {1, -1, 0, 0, 0};

typedef long double LD;
typedef complex<LD> Point;
typedef pair<Point, Point> Line;
typedef vector<Point> Polygon;
const LD EPS = 1e-10;
#define X real() // x座標を取得
#define Y imag() // y座標を取得
#define LE(n, m) ((n) < (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))
#define EQ(n, m) (abs((n) - (m)) < EPS)

// 内積 Dot(a, b) = |a||b|cosθ
LD Dot(Point a, Point b) { return (conj(a) * b).X; }

// 外積 Cross(a, b) = |a||b|sinθ
LD Cross(Point a, Point b) { return (conj(a) * b).Y; }

int CCW(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (Cross(b, c) > 0)
    return +1; // counter clockwise
  if (Cross(b, c) < 0)
    return -1; // clockwise
  if (Dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

//*********************************************
//          点と線(Point and Line)            *
//*********************************************

// 交差判定 (Isec) ****************************
// 点　 := 平面座標にある点
// 直線 := 点と点を通るどこまでも続く線
// 線分 := 点と点を結んでその両端で止まっている線

// 直線と点
bool IsecLP(Point a1, Point a2, Point b) { return abs(CCW(a1, a2, b)) != 1; }

// 直線と直線
bool IsecLL(Point a1, Point a2, Point b1, Point b2) {
  return !IsecLP(a2 - a1, b2 - b1, 0) || IsecLP(a1, b1, b2);
}

// 直線と線分
bool IsecLS(Point a1, Point a2, Point b1, Point b2) {
  return Cross(a2 - a1, b1 - a1) * Cross(a2 - a1, b2 - a1) < EPS;
}

// 線分と線分
bool IsecSS(Point a1, Point a2, Point b1, Point b2) {
  return CCW(a1, a2, b1) * CCW(a1, a2, b2) <= 0 &&
         CCW(b1, b2, a1) * CCW(b1, b2, a2) <= 0;
}

// 線分と点
bool IsecSP(Point a1, Point a2, Point b) { return !CCW(a1, a2, b); }

// ********************************************

// 距離 (Dist) ********************************
// 点pの直線aへの射影点を返す
Point Proj(Point a1, Point a2, Point p) {
  return a1 + Dot(a2 - a1, p - a1) / norm(a2 - a1) * (a2 - a1);
}

// 点pの直線aへの反射点を返す
Point Reflection(Point a1, Point a2, Point p) {
  return 2.0L * Proj(a1, a2, p) - p;
}

// 点と点
LD DistPP(Point a, Point b) { return abs(a - b); }

// 直線と点
LD DistLP(Point a1, Point a2, Point p) { return abs(Proj(a1, a2, p) - p); }

// 直線と直線
LD DistLL(Point a1, Point a2, Point b1, Point b2) {
  return IsecLL(a1, a2, b1, b2) ? 0 : DistLP(a1, a2, b1);
}

// 直線と線分
LD DistLS(Point a1, Point a2, Point b1, Point b2) {
  return IsecLS(a1, a2, b1, b2) ? 0
                                : min(DistLP(a1, a2, b1), DistLP(a1, a2, b2));
}

// 線分と点
LD DistSP(Point a1, Point a2, Point p) {
  if (Dot(a2 - a1, p - a1) < EPS)
    return abs(p - a1);
  if (Dot(a1 - a2, p - a2) < EPS)
    return abs(p - a2);
  return abs(Cross(a2 - a1, p - a1)) / abs(a2 - a1);
}

// 線分と線分
LD DistSS(Point a1, Point a2, Point b1, Point b2) {
  if (IsecSS(a1, a2, b1, b2))
    return 0;
  return min(min(DistSP(a1, a2, b1), DistSP(a1, a2, b2)),
             min(DistSP(b1, b2, a1), DistSP(b1, b2, a2)));
}

// ********************************************

// 2直線の交点 (CrossPoint) *******************
Point CrossPointLL(Point a1, Point a2, Point b1, Point b2) {
  LD d1 = Cross(b2 - b1, b1 - a1);
  LD d2 = Cross(b2 - b1, a2 - a1);
  if (EQ(d1, 0) && EQ(d2, 0))
    return a1;
  if (EQ(d2, 0))
    throw "not exist crosspoint";
  return a1 + d1 / d2 * (a2 - a1);
}
// ********************************************

//*********************************************
//             多角形(Polygon)                *
//*********************************************

namespace std {
bool operator<(Point a, Point b) { return a.X != b.X ? a.X < b.X : a.Y < b.Y; }
} // namespace std

// 多角形の面積 (PolygonErea) *****************
LD PolygonErea(Polygon p) {
  LD area = 0;
  int n = p.size();
  for (int i = 0; i < n; i++) {
    area += Cross(p[i], p[(i + 1) % n]);
  }
  return area / 2;
}
// ********************************************

// 凸性判定 (IsConvex) ************************
bool IsConvex(Polygon pol) {
  int n = pol.size();
  for (int i = 0; i < n; i++) {
    if (CCW(pol[i], pol[(i + 1) % n], pol[(i + 2) % n]) == -1)
      return false;
  }
  return true;
}
// ********************************************

// 多角形-点包含関係 (PolygonPointContainment)
int PolygonPointContainment(Polygon pol, Point p) {
  enum { OUT, ON, IN };
  bool in = false;
  int n = pol.size();
  for (int i = 0; i < n; i++) {
    Point a = pol[i] - p, b = pol[(i + 1) % n] - p;
    if (a.Y > b.Y)
      swap(a, b);
    if (a.Y <= 0 && 0 < b.Y && Cross(a, b) < 0)
      in = !in;
    if (Cross(a, b) == 0 && Dot(a, b) <= 0)
      return ON;
  }
  return in ? IN : OUT;
}
// ********************************************

//*********************************************
//          凸多角形(ConvexPolygon)           *
//*********************************************

// 凸包[θ<=180] (ConvexHull) *****************
Polygon ConvexHull(Polygon pol) {
  int n = pol.size(), k = 0;
  sort(pol.begin(), pol.end());
  Polygon ch(2 * n);
  for (int i = 0; i < n; ch[k++] = pol[i++])
    while (k >= 2 && CCW(ch[k - 2], ch[k - 1], pol[i]) == -1)
      --k;

  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = pol[i--])
    while (k >= t && CCW(ch[k - 2], ch[k - 1], pol[i]) == -1)
      --k;

  ch.resize(k - 1);
  return ch;
}
// ********************************************

// 凸包[θ<180] (ConvexHull2) *****************
Polygon ConvexHull2(Polygon pol) {
  int n = pol.size(), k = 0;
  sort(pol.begin(), pol.end());
  Polygon ch(2 * n);
  for (int i = 0; i < n; ch[k++] = pol[i++])
    while (k >= 2 && CCW(ch[k - 2], ch[k - 1], pol[i]) <= 0)
      --k;

  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = pol[i--])
    while (k >= t && CCW(ch[k - 2], ch[k - 1], pol[i]) <= 0)
      --k;

  ch.resize(k - 1);
  return ch;
}
// ********************************************

// 凸多角形の直径 (ConvexPolygonDiameter) *****
pair<int, int> ConvexPolygonDiameter(Polygon cpol) {
  int n = cpol.size();
  int i = min_element(cpol.begin(), cpol.end()) - cpol.begin();
  int j = min_element(cpol.begin(), cpol.end()) - cpol.begin();
  int maxi, maxj;
  LD maxd = 0;
  for (; i < 2 * n; i++) {
    if (maxd < norm(cpol[i] - cpol[j])) {
      maxd = norm(cpol[i] - cpol[j]);
      maxi = i;
      maxj = j;
    }
    if (Cross(cpol[(i + 1) % n] - cpol[i], cpol[(j + 1) % n] - cpol[j]) <= 0)
      j = (j + 1) % n;
    else
      i = (i + 1) % n;
  }
  return make_pair(maxi, maxj);
}
// ********************************************

// 凸多角形-点包含関係 (ConvexPolygonPointContainment)
int ConvexPolygonPointContainment(Polygon cpol, Point p) {
  enum { OUT, ON, IN };
  int n = cpol.size();
  Point g = (cpol[0] + cpol[n / 3] + cpol[2 * n / 3]) / 3.0L;
  int a = 0, b = n;
  while (a + 1 < b) {
    int c = (a + b) / 2;
    if (Cross(cpol[a] - g, cpol[c] - g) > 0) {
      if (Cross(cpol[a] - g, p - g) > 0 && Cross(cpol[c] - g, p - g) < 0)
        b = c;
      else
        a = c;
    } else {
      if (Cross(cpol[a] - g, p - g) < 0 && Cross(cpol[c] - g, p - g) > 0)
        a = c;
      else
        b = c;
    }
  }
  b %= n;
  if (Cross(cpol[a] - p, cpol[b] - p) < 0)
    return OUT;
  if (Cross(cpol[a] - p, cpol[b] - p) > 0)
    return IN;
  return ON;
}
// ********************************************

/************** using variables ***************/
Polygon p;
int n;
int q;
/**********************************************/

signed main() {
  cin >> n;
  REP(i, n) {
    LD xp, yp;
    cin >> xp >> yp;
    p.pb(Point(xp, yp));
  }
  pair<int, int> ans = ConvexPolygonDiameter(p);
  printf("%.9Lf\\n", DistPP(p[ans.first], p[ans.second]));
}