bzoj4520: [Cqoi2016]K远点对

KD-tree裸题切切,人生有什么希望

找最远点对只要记录最大值,同样,找k远点对只要维护当前前k大值,每次和第k大比较即可。

//听说加const会变快?@lych_cys

#include
#include
#include
#include
#define ll long long
#define N 100005
#define inf 1000000000
using namespace std;
int n,k,Rt,Q[2],D;
struct KD_node{int d[2],Mx[2],Mn[2],ls,rs;}T[N];
priority_queue,greater >q;
void Max(int &x,const int &y){if(xy)x=y;}
ll sqr(const int &x){return (ll)x*x;}
bool cmp(const KD_node &x,const KD_node &y){return x.d[D]>1;D=now;k=mid;
	nth_element(T+l,T+mid,T+r+1,cmp);
	for (int i=0;i<2;i++)
		T[k].Mx[i]=T[k].Mn[i]=T[k].d[i];
	if (lmid) build(T[k].rs,mid+1,r,now^1);
	update(k);
}
ll ask(int k)
{
	if (!k) return 0;
	return max(sqr(T[k].Mn[0]-Q[0]),sqr(T[k].Mx[0]-Q[0]))+
		   max(sqr(T[k].Mn[1]-Q[1]),sqr(T[k].Mx[1]-Q[1]));
}
void qry(int k)
{
	ll dis=sqr(T[k].d[0]-Q[0])+sqr(T[k].d[1]-Q[1]);
	if (dis>q.top()) q.pop(),q.push(dis);
	ll Dl=ask(T[k].ls),Dr=ask(T[k].rs);
	if (Dl>Dr)
	{
		if (Dl>q.top()) qry(T[k].ls);
		if (Dr>q.top()) qry(T[k].rs);
	}
	else
	{
		if (Dr>q.top()) qry(T[k].rs);
		if (Dl>q.top()) qry(T[k].ls);
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++)
		scanf("%d%d",&T[i].d[0],&T[i].d[1]);
	build(Rt,1,n,0);
	for (int i=1;i<=2*k;i++)q.push(0);
	for (int i=1;i<=n;i++)
		Q[0]=T[i].d[0],Q[1]=T[i].d[1],qry(Rt);
	printf("%lld\n",q.top());
	return 0;
}



你可能感兴趣的:(bzoj,KD-tree,KD-tree)