BZOJ AC 300 紀念!!!
做K次凸包,每次旋轉卡殼找到一對最遠點,刪掉他們並把他們構成的點對加入候選集合
於是候選集合的大小爲O(nk)的
總複雜度O(nklogn)
(好像會T)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
#define tra(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
const int inf=2*(1e9);
const int N=100000+5;
vector<ll>d[205];
struct point{
ll x,y;
int id;
bool operator < (const point &p)const{
return x==p.x?y<p.y:x<p.x;
}
}p[N],ch[N];
bool del[N];
point operator - (point a,point b){
return (point){a.x-b.x,a.y-b.y};
}
ll cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
ll cross(point a,point b,point c){
return cross(b-a,c-a);
}
ll sqr(ll x){return x*x;}
ll dist(point a,point b){
return sqr(a.x-b.x)+sqr(a.y-b.y);
}
int n,m,tot;
void andrew(){
m=0;
rep(i,1,n){
if(del[p[i].id])continue;
while(m>1&&cross(ch[m-2],ch[m-1],p[i])<=0)m--;
ch[m++]=p[i];
}
int k=m;
per(i,n-1,1){
if(del[p[i].id])continue;
while(m>k&&cross(ch[m-2],ch[m-1],p[i])<=0)m--;
ch[m++]=p[i];
}
if(n)m--;
}
void insert(point t){
tot++;
del[t.id]=true;
rep(k,1,n)
if(!del[p[k].id])
d[tot].push_back(dist(t,p[k]));
sort(d[tot].begin(),d[tot].end());
}
bool in(int id){
rep(i,0,m)if(ch[i].id==id)return true;
return false;
}
int find(int x){
rep(i,0,m)if(ch[i].id==x)return i;
return -1;
}
ll iabs(ll x){return x<0?-x:x;}
ll area(point a,point b,point c){
return iabs(cross(a,b,c));
}
void rotating(){
if(m==2){
insert(ch[0]);insert(ch[1]);
return ;
}
point p1,p2;
ll mx=-1;
int j=1;
rep(i,0,m-1){
while(area(ch[i],ch[i+1],ch[j])<area(ch[i],ch[i+1],ch[j+1]))j=(j+1)%m;
if(dist(ch[i],ch[j])>mx)
mx=dist(ch[i],ch[j]),
p1=ch[i],p2=ch[j];
}
insert(p1);insert(p2);
}
struct Node{
ll d;
int i,j;
bool operator < (const Node &x)const{
return d<x.d;
}
};
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int t,k;scanf("%d%d",&n,&k);t=n;
rep(i,1,n)scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
sort(p+1,p+1+n);
rep(i,1,k){
if(t==1)break;
andrew();
rotating();
t-=2;
}
priority_queue<Node>q;
rep(i,1,tot)
if((int)d[i].size())
q.push((Node){d[i][(int)d[i].size()-1],i,(int)d[i].size()-1});
k--;
while(k--){
Node tmp=q.top();q.pop();
if(!tmp.j)continue;
q.push((Node){d[tmp.i][tmp.j-1],tmp.i,tmp.j-1});
}
printf("%lld\n",q.top().d);
return 0;
}