题目描述:
RT。
题目分析:
点(x[0],x[1]…x[D])到矩形的最近距离的估价函数为:
int ret=0,tmp;
for(int j=0;j<D;j++) tmp=max(x[j]-t[i].mx[j],0)+max(t[i].mn[j]-x[j],0),ret+=tmp*tmp;
Code:
#include<bits/stdc++.h>
#define maxn 50005
using namespace std;
const int inf = 2147483646;
int n,m,k,D,id[maxn],rt,x[5];
struct node{
int d[5],mn[5],mx[5],ch[2];
void upd(node *t){
for(int i=0;i<D;i++) mn[i]=mx[i]=d[i];
for(int i=0;i<2;i++) if(ch[i]) for(int j=0;j<D;j++) mn[j]=min(mn[j],t[ch[i]].mn[j]),mx[j]=max(mx[j],t[ch[i]].mx[j]);
}
}t[maxn];
struct Pt{
int x,y;
bool operator < (const Pt &p)const{return x<p.x;}
};
priority_queue<Pt>S;
template<int D>bool cmp(int i,int j){return t[i].d[D]<t[j].d[D];}
bool (*fun[5])(int i,int j)={cmp<0>,cmp<1>,cmp<2>,cmp<3>,cmp<4>};
void build(int &i,int l,int r,int nd){
if(l>r) {i=0;return;}
int o=(l+r)>>1;nth_element(id+l,id+o,id+r+1,fun[nd]),i=id[o];
build(t[i].ch[0],l,o-1,(nd+1)%D),build(t[i].ch[1],o+1,r,(nd+1)%D);
t[i].upd(t);
}
#define sqr(x) ((x)*(x))
inline int G(int i){
if(!i) return inf;
int ret=0,tmp;
for(int j=0;j<D;j++) tmp=max(x[j]-t[i].mx[j],0)+max(t[i].mn[j]-x[j],0),ret+=tmp*tmp;
return ret;
}
inline void ins(int i){
Pt now=(Pt){0,i};
for(int j=0;j<D;j++) now.x+=sqr(x[j]-t[i].d[j]);
if(S.size()<k) S.push(now);
else if(now<S.top()) S.pop(),S.push(now);
}
void query(int i){
ins(i);
int tmp[2]={G(t[i].ch[0]),G(t[i].ch[1])};int p=tmp[1]<tmp[0];
if(t[i].ch[p]&&(S.size()<k||tmp[p]<S.top().x)) query(t[i].ch[p]);
p^=1;
if(t[i].ch[p]&&(S.size()<k||tmp[p]<S.top().x)) query(t[i].ch[p]);
}
inline void output(){
if(!S.empty()){
int i=S.top().y; S.pop(),output();
for(int j=0;j<D;j++) printf("%d%c",t[i].d[j]," \n"[j==D-1]);
}
}
int main()
{
while(~scanf("%d%d",&n,&D)){
for(int i=1;i<=n;i++) {id[i]=i;for(int j=0;j<D;j++) scanf("%d",&t[i].d[j]);}
build(rt,1,n,0);
scanf("%d",&m);
while(m--){
for(int i=0;i<D;i++) scanf("%d",&x[i]); scanf("%d",&k);
printf("the closest %d points are:\n",k);
query(rt),output();
}
}
}