辣鸡计算几何,写的我意识模糊
我们知道每次的最远点一定在凸包上面
于是我们就可以每次搞出来凸包,然后卡壳最远点,保存一些点乱搞一发就可以了
最开始想用堆维护结果委的不行
/* *********************************************** Author :BPM136 Created Time :2016/4/19 19:07:13 File Name :B.cpp ************************************************ */ #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> #include<cstring> #include<iomanip> #include<bitset> #include<queue> #include<ctime> #include<set> #include<utility> #include<vector> #include<functional> #include<numeric> #include<memory> #include<iterator> #define LL long long #define DB double #define LB long double #define UL unsigned long #define ULL unsigned long long #define get(a,i) a&(1<<(i-1)) #define PAU putchar(32) #define ENT putchar(10) #define clr(a,b) memset(a,b,sizeof(a)) #define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++) #define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--) #define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next) #define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout); #define mkd(x) freopen(#x".in","w",stdout); #define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p)); #define end system("pause") using namespace std; LL read() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} return f*d; } LL readln() { LL f=1,d=0;char s=getchar(); while (s<48||s>57){if (s==45) f=-1;s=getchar();} while (s>=48&&s<=57){d=d*10+s-48;s=getchar();} while (s!=10) s=getchar(); return f*d; } inline void write(LL x) { if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x; int len=0,buf[20];while(x)buf[len++]=x%10,x/=10; for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return; } inline void writeln(LL x){write(x);ENT;} #define N 100005 #define K 105 struct point { LL x,y; DB ag; void OUT() { write(x);PAU;write(y); } }po[N]; struct node { LL len; int id,id2; bool operator<(const node &a)const { return (LL)len<a.len; } void OUT() { cout<<len<<endl; cout<<po[id].x<<' '<<po[id].y<<endl; cout<<po[id2].x<<' '<<po[id2].y<<endl; cout<<endl; } }; int n,m; LL cross(int p,int a,int b){ LL x1=po[a].x-po[b].x; LL y1=po[a].y-po[b].y; LL x2=po[p].x-po[a].x; LL y2=po[p].y-po[a].y; return x1*y2-x2*y1; } LL cross(point p,point a,point b){ LL x1=a.x-b.x; LL y1=a.y-b.y; LL x2=p.x-a.x; LL y2=p.y-a.y; return x1*y2-x2*y1; } bool cmppoint(point a,point b){ LL cj=cross(a,b,po[1]); return cj<0; } int tb[N],nm=0; void Graham(){ int k=1; fo(i,2,n){ if(po[k].y>po[i].y||(po[k].y==po[i].y&&po[k].x>po[i].x))k=i; } swap(po[k],po[1]);tb[++nm]=1; sort(po+2,po+n+1,cmppoint); // fo(i,1,n)cout<<po[i].x<<' '<<po[i].y<<endl;cout<<endl; fo(i,2,n){ while(nm>1&&cross(i,tb[nm],tb[nm-1])<0)nm--; tb[++nm]=i; } // fo(i,1,nm)cout<<tb[i]<<' ';cout<<endl; // fo(i,1,nm)cout<<po[tb[i]].x<<' '<<po[tb[i]].y<<endl;cout<<endl; } priority_queue<node>q; LL calc(int a,int b){ return (LL)(po[a].x-po[b].x)*(po[a].x-po[b].x)+(po[a].y-po[b].y)*(po[a].y-po[b].y); } int lft[N]; void RCA(){ int k=1; memset(lft,0,sizeof(lft)); fo(i,1,nm){ while(calc(tb[i],tb[k])<calc(tb[i],tb[k%nm+1]))k=k%nm+1; node t;t.len=calc(tb[i],tb[k]), t.id=tb[i], t.id2=tb[k]; if(lft[tb[k]]!=tb[i]){ q.push(t); } lft[tb[i]]=tb[k]; if(lft[tb[k]]==0||t.len>calc(lft[tb[k]],tb[k]))lft[tb[k]]=tb[i]; } } LL Ans[N+K]; bitset<N>v; /* void work(){ int Times=0; while(Times<m) { node t=q.top();q.pop();int mxlen=0;int mxid=-1,now=t.id; t.OUT(); fo(j,1,n){ if(j==t.id2||j==t.id)continue; if(mxid==-1&&calc(now,j)<t.len)mxid=j; else { int tmplen=calc(now,j); if(tmplen>t.len)continue; if(tmplen>mxlen){ mxlen=tmplen; mxid=j; } } } if(mxid!=-1){ t.len=mxlen; t.id2=mxid; q.push(t); Times++; } } cout<<"Ans::"<<' '<<q.top().len<<endl; node tt=q.top();tt.OUT(); fo(i,1,n)po[i].OUT(); } */ bool cmpAns(LL a,LL b){ return a>b; } /* int tmp[K],nk=0; void work() { v.reset();int tt=0; while(1){ node t=q.top();q.pop(); int x=t.id,y=t.id2; if(x>y)swap(x,y); if(v[y]==1)continue; if(v[x]==1)continue; fo(i,1,n){ if(v[i])continue; if(i==y)continue; int tmplen=calc(i,y); if(nk==0||tmplen>tmp[m])Ans[++tt]=tmplen; po[i].OUT();PAU;po[y].OUT();ENT;writeln(tmplen); } if(tt<m)continue; sort(Ans+1,Ans+tt+1,cmpAns); if(nk==0){ fo(i,1,m)tmp[++nk]=i; tt=m; }else{ int flag=1; fo(i,1,m){ if(tmp[i]!=Ans[i])flag=0; tmp[i]=Ans[i]; } tt=m; if(flag)return; } v[y]=1; fo(i,1,m)cout<<Ans[i]<<' ';cout<<endl; } } */ LL calc(point a,point b){ LL x=a.x-b.x; LL y=a.y-b.y; return x*x+y*y; } const DB eps=1e-10; bool cmppo(point a,point b){ if(fabs(a.ag-b.ag)<eps)return calc(po[1],a)<calc(po[1],b); return a.ag<b.ag; } void work(){ Ans[0]=-1;int kt=1;v.reset(); fo(i,2,n){ if(po[kt].y>po[i].y||(po[kt].y==po[i].y&&po[kt].x>po[i].x))kt=i; } swap(po[kt],po[1]); fo(i,2,n){ po[i].ag=atan2(po[i].y-po[1].y,po[i].x-po[1].x); } sort(po+2,po+n+1,cmppo); int Ansnum=0; // fo(i,1,n)cout<<po[i].x<<' '<<po[i].y<<endl;cout<<endl; fo(Times,1,m){ nm=0; fo(i,1,n){ if(v[i])continue; while(nm>1&&cross(i,tb[nm],tb[nm-1])<0)nm--; tb[++nm]=i; } tb[0]=tb[nm];tb[nm+1]=tb[1]; int k=1;LL tmpAns=-1;int Ansi,Ansj; fo(i,1,nm){ while((LL)calc(tb[i],tb[k])<=calc(tb[i],tb[k%nm+1]))k=k%nm+1; if(calc(tb[i],tb[k])>tmpAns){ tmpAns=calc(tb[i],tb[k]); Ansi=tb[i], Ansj=tb[k]; } } if(Ansi>Ansj)swap(Ansi,Ansj); v[Ansj]=1;int kn=0; fo(i,1,n){ if(v[i])continue; if(calc(i,Ansj)>Ans[Ansnum]){ Ans[Ansnum+(++kn)]=calc(i,Ansj); } } if(kn==0)break; sort(Ans+1,Ans+Ansnum+kn+1,cmpAns); Ansnum=min(m,Ansnum+kn); } } int main() { file(B); n=read(),m=read(); fo(i,1,n){ po[i].x=read(); po[i].y=read(); } // Graham(); // RCA(); work(); writeln(Ans[m]); return 0; }