凸包旋转卡壳
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 50010
#define epx 1e-8
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,top;
double Ans;
struct Point{
double x,y;
Point operator - (const Point &a) const{
Point tmp;
tmp.x=x-a.x,tmp.y=y-a.y;
return tmp;
}
double operator * (const Point &a) const{
return x*a.y-y*a.x;
}
}p[N],S[N];
double Dis(Point a,Point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool Cmp(const Point &a,const Point &b)
{
if(fabs((b-p[1])*(a-p[1]))<epx)
return Dis(a,p[1])<Dis(b,p[1]);
else return (a-p[1])*(b-p[1])>0;
}
void Graham()
{
int t=1;
for(int i=2;i<=n;i++)
if(p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x))
t=i;
swap(p[1],p[t]);
sort(p+2,p+n+1,Cmp);
S[++top]=p[1];S[++top]=p[2];
for(int i=3;i<=n;i++)
{
while((S[top]-S[top-1])*(p[i]-S[top-1])<=epx&&top>1)
top--;
S[++top]=p[i];
}
}
void RC()
{
S[top+1]=p[1];
int now=2;
for(int i=1;i<=top;i++)
{
while((S[i+1]-S[i])*(S[now]-S[i])<(S[i+1]-S[i])*(S[now+1]-S[i]))
{
now++;
if(now==top+1)now=1;
}
Ans=max(Ans,max(Dis(S[now],S[i+1]),Dis(S[now],S[i])));
}
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
p[i].x=read(),p[i].y=read();
Graham();RC();
printf("%lld\n",(long long)Ans);
return 0;
}