bzoj 4520: [Cqoi2016]K远点对 k-d tree

       用优先队列维护一下最大的k个,然后和第k个比较看能否更新即可。枚举每个点直接在k-d tree里面查询,这样会造成重复就把k变成2k即可。

AC代码如下:

#include
#include
#include
#include
#include
#define ll long long
#define sqr(x) (ll)(x)*(x)
using namespace std;

int n,m,dms,tx,ty,rt,h[100005];
void up(int &x,int y){ if (xy) x=y; }
priority_queue,greater > q;
struct node{
	int d[2],x[2],y[2],ls,rs;
	void pfs(int u,int v){
		d[0]=x[0]=x[1]=u; d[1]=y[0]=y[1]=v;
	}
}p[100005];
bool cmp(int x,int y){ return p[x].d[dms]>1; dms=now;
		nth_element(h+l,h+mid,h+r+1,cmp); k=h[mid];
		if (lq.top()){ q.pop(); q.push(dk); }
		if (dl>dr){
			if (p[k].ls && dl>q.top()) qry(p[k].ls,now^1);
			if (p[k].rs && dr>q.top()) qry(p[k].rs,now^1);
		} else{
			if (p[k].rs && dr>q.top()) qry(p[k].rs,now^1);
			if (p[k].ls && dl>q.top()) qry(p[k].ls,now^1);
		}
	}
}kd;
int main(){
	scanf("%d%d",&n,&m); int i,x,y;
	for (i=1; i<=n; i++){
		h[i]=i; scanf("%d%d",&x,&y);
		p[i].pfs(x,y);
	}
	kd.build(rt,1,n,0);
	for (i=1; i<=(m<<1); i++) q.push(0);
	for (i=1; i<=n; i++){
		tx=p[i].d[0]; ty=p[i].d[1];
		kd.qry(rt,0);
	}
	printf("%lld\n",q.top());
	return 0;
}


by lych

2016.4.14

你可能感兴趣的:(bzoj)