题目大意:给定平面上的n个点,定义距离为曼哈顿距离,求一个点到其他所有点的最大距离与最小距离之差最小
KDTree……这东西好神啊
注意计算最小距离的时候不能把自己也算进去= =
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 #define INF 0x3f3f3f3f using namespace std; struct Point{ int x,y; Point() {} Point(int _,int __): x(_),y(__) {} friend istream& operator >> (istream &_,Point &p) { scanf("%d%d",&p.x,&p.y); return _; } friend bool operator != (const Point &p1,const Point &p2) { return p1.x!=p2.x || p1.y!=p2.y ; } friend int Distance(const Point &p1,const Point &p2) { return abs(p1.x-p2.x) + abs(p1.y-p2.y); } }points[M]; int n,ans=INF; bool Compare_x(const Point &p1,const Point &p2) { return p1.x < p2.x; } bool Compare_y(const Point &p1,const Point &p2) { return p1.y < p2.y; } namespace K_Dimension_Tree{ struct abcd{ abcd *ls,*rs; Point p; int x1,y1,x2,y2; abcd() {} abcd(const Point &_):p(_) { x1=x2=p.x; y1=y2=p.y; } void Push_Up(abcd *x) { x1=min(x->x1,x1); x2=max(x->x2,x2); y1=min(x->y1,y1); y2=max(x->y2,y2); } int Min_Distance(const Point &p) { int re=0; if(p.x<x1) re+=x1-p.x; if(p.x>x2) re+=p.x-x2; if(p.y<y1) re+=y1-p.y; if(p.y>y2) re+=p.y-y2; return re; } int Max_Distance(const Point &p) { int re=0; re+=max(p.x-x1,x2-p.x); re+=max(p.y-y1,y2-p.y); return re; } }mempool[M],*C=mempool,*root; void Build_Tree(abcd *&x,int l,int r,bool flag) { if(l>r) { x=0x0; return ; } int mid=l+r>>1; nth_element(points+l,points+mid,points+r+1,flag?Compare_y:Compare_x); x=new (C++)abcd(points[mid]); Build_Tree(x->ls,l,mid-1,flag^1); Build_Tree(x->rs,mid+1,r,flag^1); if(x->ls) x->Push_Up(x->ls); if(x->rs) x->Push_Up(x->rs); } void Get_Min(abcd *x,const Point &p,int &ans) { if(x->p!=p) ans=min(ans,Distance(x->p,p)); int l_dis=x->ls?x->ls->Min_Distance(p):INF; int r_dis=x->rs?x->rs->Min_Distance(p):INF; if( l_dis < r_dis ) { if( x->ls && l_dis<ans ) Get_Min(x->ls,p,ans); if( x->rs && r_dis<ans ) Get_Min(x->rs,p,ans); } else { if( x->rs && r_dis<ans ) Get_Min(x->rs,p,ans); if( x->ls && l_dis<ans ) Get_Min(x->ls,p,ans); } } void Get_Max(abcd *x,const Point &p,int &ans) { ans=max(ans,Distance(x->p,p)); int l_dis=x->ls?x->ls->Max_Distance(p):-INF; int r_dis=x->rs?x->rs->Max_Distance(p):-INF; if( l_dis > r_dis ) { if( x->ls && l_dis>ans ) Get_Max(x->ls,p,ans); if( x->rs && r_dis>ans ) Get_Max(x->rs,p,ans); } else { if( x->rs && r_dis>ans ) Get_Max(x->rs,p,ans); if( x->ls && l_dis>ans ) Get_Max(x->ls,p,ans); } } } int main() { using namespace K_Dimension_Tree; int i; cin>>n; for(i=1;i<=n;i++) cin>>points[i]; Build_Tree(root,1,n,0); for(i=1;i<=n;i++) { int min_dis=INF,max_dis=0; Get_Min(root,points[i],min_dis); Get_Max(root,points[i],max_dis); ans=min(ans,max_dis-min_dis); } cout<<ans<<endl; return 0; }