Analysis: K_d tree template problem, reference to other people's writing; when dividing, the efficiency of using the coordinate span as the dividing basis is slightly higher than the depth of the tree; the nth_element function is more efficient than the sort function, and it can be improved by using GETCHAR and putchar efficiency.
#include <iostream> #include <algorithm>using namespace std;struct point{int x, y;}; struct K_d_node{point mid; Split midpoint int split_axis; Divided axes, 0 x-axis, 1 y-axis k_d_node* child[2]; 0 left child node, 1 right child node}; #define N 100100const __int64 inf=0x7fffffffffffffff; Point P[n],p2[n]; K_d_node k_d_tree[n];int len;__int64 ans;bool cmpx (const point& a,const point& b) {return a.x<b.x;} BOOL Cmpy (const point& a,const point& b) {return a.y<b.y;} k_d_node* Mallocnode () {K_d_tree[len].child[0]=k_d_tree[len].child[1]=null;return &K_D_Tree[len++];} k_d_node* build_tree (int l,int r,int depth) {int mid,t; k_d_node* q;int minx,miny,maxx,maxy;if (l>r) return Null;q=mallocnode ();//----------------------//t=depth%2; Use the depth of the tree as the basis for segmentation//---------------------minx=min_element (P+L,P+R,CMPX)->x; Use the coordinate span as the basis for dividing the miny=min_element (p+l,p+r,cmpy)->y;maxx=max_element (p+l,p+r,cmpx)->x;maxy=max_element (p+L,p+ R,cmpy)->y;if (maxx-minx>=maxy-miny) t=0;elset=1;q->spLit_axis=t;if (l==r) {Q->mid=p[l];return q;} Mid= (l+r) >>1;if (t==0)//X-axis Division nth_element (P+L,P+MID,P+R+1,CMPX);//sort (P+L,P+R+1,CMPX); Elsenth_elem ENT (p+l,p+mid,p+r+1,cmpy);//sort (p+l,p+r+1,cmpy); Q->mid=p[mid];q->child[0]=build_tree (L,mid-1,depth+1); Build left subtree Q->child[1]=build_tree (mid+1,r,depth+1); return q;} __int64 DIS (const point& a,const point& b) {__int64 Xx,yy;xx=a.x-b.x;yy=a.y-b.y;return (__int64) xx*xx+ (__int64 ) Yy*yy;} void Query (k_d_node* q,const point& a) {int tmp,s;__int64 dis; Distance squared if (q==null) return; if (q->split_axis==0)//x axis {tmp=q->mid.x;s=a.x;} Else//y axis {tmp=q->mid.y;s=a.y;} if (s<=tmp) Query (q->child[0],a); Left Dial hand tree elsequery (q->child[1],a);d Is=dis (q->mid,a); if (dis && dis<ans)//Note It must be updated if dis is not equal to 0, avoid processing to its own point , if there are duplicates in the input, you cannot process ans=dis;if ((__int64) (tmp-s) * (tmp-s) <ans)//may be in the other half, look for the other half {if (s<=tmp) Query (q->child[1],a) ; Elsequery (Q->child[0],a);}} int ReadInt () {int ans; CHar c; C=getchar (); while (c< ' 0 ' | | c> ' 9 ') C=getchar (); ans=c-' 0 '; while ((C=getchar ()) >= ' 0 ' && c<= ' 9 ') {ans=ans*10+c-' 0 '; } return ans; }void PutInt64 (__int64 x) {int b[32],i; i=0; while (x) {b[i++]=x%10; x/=10; } for (i--;i>=0;i--) putchar (b[i]+ ' 0 '); }int Main () {int t,n,i; k_d_node* Root;t=readint (), while (t--) {n=readint (), for (i=0;i<n;i++) {p[i].x=readint ();p [I].y=readint ();p 2[i]=p [i];} Len=0;root=build_tree (0,n-1,0); Establish K_d tree for (i=0;i<n;i++) {ans=inf; Query (Root,p2[i]); PutInt64 (ANS);p utchar (' \ n ');}} return 0;}
HDU ACM 2966 in case of failure->k_d tree template title