解题:洛谷2093 JZPFAR

题面

初见K-D Tree

其实这样的题(欧几里得距离第$x$近点对)不应该用K-D Tree做,因为会被构造数据卡成$O(n^2)$,随机的另说。

但是并没有找到合适的K-D Tree的题(区域统计),于是就凑活着写了,代码极丑预警

  1 // luogu-judger-enable-o2
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cctype>
  5 #include<cstring>
  6 #include<algorithm>
  7 using namespace std;
  8 const int N=100005;
  9 const long long inf=1e9;
 10 struct a
 11 {
 12     int id; 
 13     long long ds;
 14 };
 15 bool operator < (a x,a y)
 16 {
 17     return x.ds==y.ds?x.id<y.id:x.ds>y.ds;
 18 }
 19 priority_queue<a> hp;
 20 struct b
 21 {
 22     int ps[2],mn[2],mx[2],sn[2],id,idn;
 23 }kdt[N],qry; 
 24 int n,m,k,r,f,typ;
 25 inline void read(int &x)
 26 {
 27     x=0,f=0; char ch=getchar();
 28     while(!isdigit(ch))
 29         f|=ch=='-',ch=getchar();
 30     while(isdigit(ch))
 31         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
 32     x=f?-x:x;
 33 }
 34 void write(int x)
 35 {
 36     if(x>9) write(x/10);
 37     putchar(x%10^48);
 38 }
 39 bool operator < (b x,b y)
 40 {
 41     return x.ps[typ]<y.ps[typ];
 42 }
 43 void Pushup(int nde)
 44 {
 45     kdt[nde].idn=kdt[nde].id;
 46     int lson=kdt[nde].sn[0],rson=kdt[nde].sn[1]; 
 47     b ls=kdt[lson],rs=kdt[rson];
 48     if(lson) kdt[nde].idn=min(kdt[nde].idn,ls.idn);
 49     if(rson) kdt[nde].idn=min(kdt[nde].idn,rs.idn);
 50     for(int i=0;i<=1;i++)
 51     {
 52         kdt[nde].mn[i]=kdt[nde].mx[i]=kdt[nde].ps[i];
 53         if(lson) kdt[nde].mn[i]=min(kdt[nde].mn[i],ls.mn[i]),kdt[nde].mx[i]=max(kdt[nde].mx[i],ls.mx[i]);
 54         if(rson) kdt[nde].mn[i]=min(kdt[nde].mn[i],rs.mn[i]),kdt[nde].mx[i]=max(kdt[nde].mx[i],rs.mx[i]);
 55     }
 56 }
 57 int Create(int l,int r,int k)
 58 {
 59     typ=k; int mid=(l+r)/2;
 60     nth_element(kdt+l,kdt+mid,kdt+r+1);
 61     if(l<mid) kdt[mid].sn[0]=Create(l,mid-1,k^1);
 62     if(r>mid) kdt[mid].sn[1]=Create(mid+1,r,k^1);
 63     Pushup(mid); return mid;
 64 }
 65 long long calc1(int nde)
 66 {
 67     long long mnx=kdt[nde].mn[0]-qry.ps[0],mxx=kdt[nde].mx[0]-qry.ps[0];
 68     long long mny=kdt[nde].mn[1]-qry.ps[1],mxy=kdt[nde].mx[1]-qry.ps[1];
 69     return max(mnx*mnx,mxx*mxx)+max(mny*mny,mxy*mxy);
 70 }
 71 long long calc2(int nde)
 72 {
 73     long long dsx=kdt[nde].ps[0]-qry.ps[0];
 74     long long dsy=kdt[nde].ps[1]-qry.ps[1];
 75     return dsx*dsx+dsy*dsy;
 76 }
 77 inline bool farther(long long x,long long y)
 78 {
 79     a t=hp.top();
 80     return x>t.ds||(x==t.ds&&y<t.id);
 81 }
 82 inline bool further(long long x,long long y)
 83 {
 84     a t=hp.top();
 85     return x>t.ds||(x==t.ds&&kdt[y].idn<t.id);
 86 }
 87 void Query(int nde)
 88 {
 89     b tmp=kdt[nde]; long long dis=calc2(nde);
 90     int idx=tmp.id,lson=tmp.sn[0],rson=tmp.sn[1];
 91     if(farther(dis,idx)) 
 92         hp.pop(),hp.push((a){idx,dis});
 93     long long d1=lson?calc1(lson):-inf,d2=rson?calc1(rson):-inf;
 94     if(d1>d2)
 95     {
 96         if(further(d1,lson)) Query(lson);
 97         if(further(d2,rson)) Query(rson);
 98     }
 99     else
100     {
101         if(further(d2,rson)) Query(rson);
102         if(further(d1,lson)) Query(lson);
103     }
104 }
105 int main()
106 {
107     register int i;
108     read(n);
109     for(i=1;i<=n;i++)
110         read(kdt[i].ps[0]),read(kdt[i].ps[1]),kdt[i].id=i;
111     r=Create(1,n,0),scanf("%d",&m);
112     while(m--)
113     {
114         while(!hp.empty()) hp.pop();
115         read(qry.ps[0]),read(qry.ps[1]),read(k);
116         for(i=1;i<=k;i++) hp.push((a){0,-inf});
117         Query(r),write(hp.top().id),puts("");
118     }
119     return 0;
120 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/10143348.html