CQOI2016 K远点对 计算几何

辣鸡计算几何,写的我意识模糊

我们知道每次的最远点一定在凸包上面

于是我们就可以每次搞出来凸包,然后卡壳最远点,保存一些点乱搞一发就可以了

最开始想用堆维护结果委的不行

/* ***********************************************
Author        :BPM136
Created Time  :2016/4/19 19:07:13
File Name     :B.cpp
************************************************ */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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)lenpo[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<1&&cross(i,tb[nm],tb[nm-1])<0)nm--;
		tb[++nm]=i;
	}
//	fo(i,1,nm)cout<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(lft[tb[k]],tb[k]))lft[tb[k]]=tb[i];
	}
}

LL Ans[N+K];
bitsetv;
/*
void work(){
	int Times=0;
	while(Timest.len)continue;
				if(tmplen>mxlen){
					mxlen=tmplen;
					mxid=j;
				}
			}
		}
		if(mxid!=-1){
			t.len=mxlen;
			t.id2=mxid;
			q.push(t);
			Times++;
		}
	}
	cout<<"Ans::"<<' '<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(ttpo[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<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;
}


你可能感兴趣的:(计算几何)