loj #2043. 「CQOI2016」K 远点对(KDTree)

题目链接:https://loj.ac/problem/2043


KDTree板题?貌似会就能过哦。


代码:

#include
using namespace std;
typedef long long ll;

namespace KD_Tree
{
	#define x first
	#define y second
	const int MAXN=2e5+5;
	const ll inf=0x3f3f3f3f3f3f3f3f;
	struct _
	{
		ll dis;
		_(ll _dis=0):dis(_dis){}
		bool operator < (const _ &a)const
		{
			return dis>a.dis;
		}
	};
	priority_queue<_> Q;
    struct node
    {
        node *ch[2];
        ll d[2],mx[2],my[2],size;//d表示这个点的坐标[0]->x,[1]->y,mx表示这个平面的x的范围,my表示这个平面的y的范围
        inline void push_up()
        {
            size=1;
            for(int i=0;i<=1;i++)
            {
                if(ch[i])
                {
                    mx[0]=min(mx[0],ch[i]->mx[0]);
                    mx[1]=max(mx[1],ch[i]->mx[1]);
                    my[0]=min(my[0],ch[i]->my[0]);
                    my[1]=max(my[1],ch[i]->my[1]);
                    size+=ch[i]->size;
                }
            }
        }
    }pool_node[MAXN],*pool_top=pool_node;
    node *del_pool[MAXN],**del_top=del_pool;
    inline node* newnode()
    {
        return del_top==del_pool?++pool_top:*(del_top--);
    }
    typedef pair Point;
    inline bool cmp_x(const Point &a,const Point &b) {return a.x>1;
        node *o=newnode();
        nth_element(stk+l,stk+mid,stk+r+1,!f?cmp_x:cmp_y);
        o->d[0]=o->mx[0]=o->mx[1]=stk[mid].x;
        o->d[1]=o->my[0]=o->my[1]=stk[mid].y;
        o->ch[0]=lch[1]=midpush_up();
        return o;
    }
    Point P;
    ll calc_mx(node *o)
    {
        ll ret=0;
        ret+=(max(P.x-o->mx[0],0LL)+max(o->mx[1]-P.x,0LL))*(max(P.x-o->mx[0],0LL)+max(o->mx[1]-P.x,0LL));
        ret+=(max(P.y-o->my[0],0LL)+max(o->my[1]-P.y,0LL))*(max(P.y-o->my[0],0LL)+max(o->my[1]-P.y,0LL));
		return ret;
    }
    node *root;
	void Query(node *o)
    {
		ll dis=(P.x-o->d[0])*(P.x-o->d[0])+(P.y-o->d[1])*(P.y-o->d[1]);
		if(dis>Q.top().dis)
		{
			Q.pop();
			Q.push(_(dis));
		}
		ll dl=o->ch[0]?calc_mx(o->ch[0]):-inf;
        ll dr=o->ch[1]?calc_mx(o->ch[1]):-inf;
		if(dl>dr)
		{
			if(dl>Q.top().dis)
				Query(o->ch[0]);
			if(dr>Q.top().dis)
				Query(o->ch[1]);
		}
		else
		{
			if(dr>Q.top().dis)
				Query(o->ch[1]);
			if(dl>Q.top().dis)
				Query(o->ch[0]);
		}
        return ;
    }
    void init()//用于初始化
    {
        del_top=del_pool,pool_top=pool_node;
    }
}
using namespace KD_Tree;
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n,k;
	init();
	scanf("%d%d",&n,&k);
	k<<=1;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&stk[i].x,&stk[i].y);
	}
	root=build(1,n,1);
	for(int i=1;i<=k;i++)
	{
		Q.push(_(0));
	}
	for(int i=1;i<=n;i++)
	{
		P=make_pair(stk[i].x,stk[i].y);
		Query(root);
	}
	printf("%lld\n",Q.top().dis);
	return 0;
}


你可能感兴趣的:(loj)