B题其实可以做到O(n log n)的时间复杂度。
我们可以对点集求一个凸包,然后对应问题就转变为求凸包的直径。可以使用旋转卡壳O(n)求解。
算法瓶颈在求凸包的排序,是O(n log n)的时间复杂度。
下面贴一下板子
using ld = long double;
const ld PI = acos(-1);
const ld EPS = 1e-7;
const ld INF = numeric_limits<ld>::max();
#define cc(x) cout << fixed << setprecision(x);
ld fgcd(ld x, ld y) { // 实数域gcd
return abs(y) < EPS ? abs(x) : fgcd(y, fmod(x, y));
}
template<class T, class S> bool equal(T x, S y) {
return -EPS < x - y && x - y < EPS;
}
template<class T> ll sign(T x) {
if (-EPS < x && x < EPS) return 0;
return x < 0 ? -1 : 1;
}
template<class T> T sqr(T x) {
return x * x;
}
template<class T> struct Point { // 在C++17下使用 emplace_back 绑定可能会导致CE!
T x, y;
Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {} // 初始化
template<class U> operator Point<U>() { // 自动类型匹配
return Point<U>(U(x), U(y));
}
Point &operator+=(Point p) & { return x += p.x, y += p.y, *this; }
Point &operator+=(T t) & { return x += t, y += t, *this; }
Point &operator-=(Point p) & { return x -= p.x, y -= p.y, *this; }
Point &operator-=(T t) & { return x -= t, y -= t, *this; }
Point &operator*=(T t) & { return x *= t, y *= t, *this; }
Point &operator/=(T t) & { return x /= t, y /= t, *this; }
Point operator-() const { return Point(-x, -y); }
friend Point operator+(Point a, Point b) { return a += b; }
friend Point operator+(Point a, T b) { return a += b; }
friend Point operator-(Point a, Point b) { return a -= b; }
friend Point operator-(Point a, T b) { return a -= b; }
friend Point operator*(Point a, T b) { return a *= b; }
friend Point operator*(T a, Point b) { return b *= a; }
friend Point operator/(Point a, T b) { return a /= b; }
friend bool operator<(Point a, Point b) {
return equal(a.x, b.x) ? a.y < b.y - EPS : a.x < b.x - EPS;
}
friend bool operator>(Point a, Point b) { return b < a; }
friend bool operator==(Point a, Point b) { return !(a < b) && !(b < a); }
friend bool operator!=(Point a, Point b) { return a < b || b < a; }
friend auto &operator>>(istream &is, Point &p) {
return is >> p.x >> p.y;
}
friend auto &operator<<(ostream &os, Point p) {
return os << "(" << p.x << ", " << p.y << ")";
}
};
template<class T> struct Line {
Point<T> a, b;
Line(Point<T> a_ = Point<T>(), Point<T> b_ = Point<T>()) : a(a_), b(b_) {}
template<class U> operator Line<U>() { // 自动类型匹配
return Line<U>(Point<U>(a), Point<U>(b));
}
friend auto &operator<<(ostream &os, Line l) {
return os << "<" << l.a << ", " << l.b << ">";
}
};
template<class T> T disEx(Pt a1,Pt a2)
{
return (a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y);
}
template<class T> T cross(Point<T> a, Point<T> b) { // 叉乘
return a.x * b.y - a.y * b.x;
}
template<class T> T cross(Point<T> p1, Point<T> p2, Point<T> p0) { // 叉乘 (p1 - p0) x (p2 - p0);
return cross(p1 - p0, p2 - p0);
}
template<class T> T dot(Point<T> a, Point<T> b) { // 点乘
return a.x * b.x + a.y * b.y;
}
template<class T> T dot(Point<T> p1, Point<T> p2, Point<T> p0) { // 点乘 (p1 - p0) * (p2 - p0);
return dot(p1 - p0, p2 - p0);
}
template <class T> ld dis(T x1, T y1, T x2, T y2) {
ld val = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
return sqrt(val);
}
template <class T> ld dis(Point<T> a, Point<T> b) {
return dis(a.x, a.y, b.x, b.y);
}
template<class T> vector<Point<T>> staticConvexHull(vector<Point<T>> &A, ll flag = 1) {
ll n = A.size();
if (n <= 2) { // 特判
return A;
}
vector<Point<T>> ans(n * 2);
sort(A.begin(), A.end());
ll now = -1;
for (ll i = 0; i < n; i++) { // 维护下凸包
while (now > 0 && cross(A[i], ans[now], ans[now - 1]) <= 0) {
now--;
}
ans[++now] = A[i];
}
ll pre = now;
for (ll i = n - 2; i >= 0; i--) { // 维护上凸包
while (now > pre && cross(A[i], ans[now], ans[now - 1]) <= 0) {
now--;
}
ans[++now] = A[i];
}
ans.resize(now);
return ans;
}
template<class T>pair<Pt,Pt> GetConvexHullDis(vector<Pt> A)//返回平方,并特判为一条线的情况
{
ll cnt=0;
for(auto ne:A)
{
if(cross(A[0],A[1],ne)!=0) break;
++cnt;
}
if(cnt==A.size())
{
Pt a1=A[0],a2=A[0];
for(auto ne:A) a1=max(a1,ne),a2=min(a2,ne);
return {a1,a2};
}
ll w=0;
T jj1=disEx(A[w],A[0]); T jj2=disEx(A[w],A[1]);
T ans=max(jj1,jj2);
pair<Pt,Pt> res;
if(jj1>jj2) res={A[w],A[0]};
else res={A[w],A[1]};
for(ll i=0;i<A.size();i++)
{
ll j=(i+1)%A.size();
ll ne=(w+1)%A.size();
while((-cross(A[ne],A[i],A[j]))>=(-cross(A[w],A[i],A[j]))) w=ne,ne=(w+1)%A.size();
jj1=disEx(A[w],A[i]); jj2=disEx(A[w],A[j]);
pair<Pt,Pt> tem;
if(jj1>jj2) tem={A[w],A[i]};
else tem={A[w],A[j]};
jj1=max(jj1,jj2);
if(ans<jj1) ans=jj1,res=tem;
}
return res;
}

京公网安备 11010502036488号