题目链接:https://loj.ac/problem/2043
KDTree板题?貌似会就能过哦。
代码:
#include<bits/stdc++.h>
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<ll,ll> Point;
inline bool cmp_x(const Point &a,const Point &b) {return a.x<b.x;}
inline bool cmp_y(const Point &a,const Point &b) {return a.y<b.y;}
node **rebuild_need;
int rebuild_d;
Point stk[MAXN];
int point_cnt;
//用于最开始建树,可以不用直接插点,方法为build(1,point_cnt,0),保证点在stk数组中
node* build(int l,int r,bool f)
{
int mid=(l+r)>>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]=l<mid?build(l,mid-1,f^1):0;
o->ch[1]=mid<r?build(mid+1,r,f^1):0;
o->push_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;
}