[Cqoi2016]K远点对 K-Dtree

4520: [Cqoi2016]K远点对

链接

bzoj

思路

用K-Dtree求点的最远距离。
求的时候顺便维护一个大小为2k的小根堆。
不知道为啥一定会对。

代码

#include <bits/stdc++.h>
#define ll long long
#define ls (t[u].ch[0])
#define rs (t[u].ch[1])
#define cmin(a,b) (a>b?a=b:a)
#define cmax(a,b) (a>b?a:a=b)
using namespace std;
const int N=1e5+7;
const ll INF=1LL<<18;
int read() {
	int x=0,f=1;char s=getchar();
	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
	return x*f;
}
priority_queue<ll,vector<ll>,greater<ll> > q;
int n,k,rt,WD;
struct point {
	int x[2];
	bool operator < (const point &b) const {
		return x[WD]<b.x[WD];
	}
}p[N];
struct node{
	int mi[2],ma[2],ch[2];
	point a;
}t[N];
void update(int x,int y) {
	cmin(t[x].mi[0],t[y].mi[0]);
	cmin(t[x].mi[1],t[y].mi[1]);
	cmax(t[x].ma[0],t[y].ma[0]);
	cmax(t[x].ma[1],t[y].ma[1]);
}
void up(int u) {
	t[u].mi[0]=t[u].ma[0]=t[u].a.x[0];
	t[u].mi[1]=t[u].ma[1]=t[u].a.x[1];
	if(ls) update(u,ls);
	if(rs) update(u,rs);
}
int build(int l,int r,int wd) {
	if(l>r) return 0;
	int mid=(l+r)>>1;
	WD=wd;
	nth_element(p+l,p+mid,p+r+1);
	int u=mid;
	t[u].a=p[mid];
	ls=build(l,mid-1,wd^1);
	rs=build(mid+1,r,wd^1);
	up(u);
	return u;
}
inline ll fff(int a){return 1LL*a*a;}
inline ll dis(point a,point b) {
	return fff(a.x[0]-b.x[0])+fff(a.x[1]-b.x[1]);
}
ll get(int u,point a) {
	ll rec=0;
	for(int i=0;i<2;++i)
		rec+=max(fff(a.x[i]-t[u].ma[i]),fff(a.x[i]-t[u].mi[i]));
	return rec;
}
void query(point a,int u) {
	ll distance=dis(a,t[u].a);
	if(q.top()<distance) q.pop(),q.push(distance);
	ll dl=-INF,dr=-INF;
	if(ls) dl=get(ls,a);
	if(rs) dr=get(rs,a);
	if(dl<dr) {
		if(q.top()<dr) query(a,rs);
		if(q.top()<dl) query(a,ls);
	} else {
		if(q.top()<dl) query(a,ls);
		if(q.top()<dr) query(a,rs);
	}
}
int main() {
	n=read(),k=read();
	for(int i=1;i<=n;++i) p[i].x[0]=read(),p[i].x[1]=read();
	rt=build(1,n,0);
	for(int i=1;i<=2*k;++i) q.push(0);
	for(int i=1;i<=n;++i) query(p[i],rt);
	printf("%lld\n",q.top());
	return 0;
}
posted @ 2019-07-17 19:33  ComplexPug  阅读(221)  评论(0编辑  收藏  举报