BZOJ 4520: [Cqoi2016]K远点对

BZOJ AC 300 纪念!!!

做K次凸包,每次旋转卡壳找到一对最远点,删掉他们并把他们构成的点对加入候选集合

于是候选集合的大小为O(nk)的

总复杂度O(nklogn)

(好像会T)

#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
vectord[205];
struct point{
	ll x,y;
	int id;
	bool operator < (const point &p)const{
		return x==p.x?y1&&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])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 dq;
	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;
}


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