STL里面的nth_element()函数
用法:nth_element(first,nth,last)
int a[maxn];
nth_element(a,a+k,a+f);
作用:在a到a+f区间内,使第k位左边的都比它小,右边的都比它大。
kdtree代码:
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) ((x)&(-x)) const double pi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=2e5+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; int kdd; struct node{ int id,g[3]; bool operator<(const node &u)const{ return g[kdd]<u.g[kdd]; } }kdt[maxn<<2],data[maxn]; bool flag[maxn<<2]; LL dis(node a,node b){ return LL(a.g[0]-b.g[0])*(a.g[0]-b.g[0])+LL(a.g[1]-b.g[1])*(a.g[1]-b.g[1]); } void build(int l,int r,int rt,int kd){ kd%=2; kdd=kd; if(l>r) return ; flag[rt]=1; int mid=(l+r)>>1; nth_element(data+l,data+mid,data+r+1); kdt[rt]=data[mid]; flag[rt<<1]=flag[rt<<1|1]=0; if(l<=mid-1){ build(l,mid,rt<<1,kd+1); } if(mid+1<=r){ build(mid+1,r,rt<<1|1,kd+1); } } pair<LL,node> ans; void query(int rt,node p,int kd){ kd%=2; pair<LL,node> now={dis(p,kdt[rt]),kdt[rt]}; int x=rt<<1; int y=rt<<1|1; if(p.g[kd]>=kdt[rt].g[kd]){ swap(x,y); } if(flag[x]) query(x,p,kd+1); bool ff=0; if(ans.fi==-1){ ff=1; if(p.g[2]>=kdt[rt].g[2]){ ans=now; } } else{ if(p.g[2]>=kdt[rt].g[2]&&(now.fi<ans.fi||now.fi==ans.fi&&now.se.id<ans.se.id)){ ans=now; } if(LL(kdt[rt].g[kd]-p.g[kd])*(kdt[rt].g[kd]-p.g[kd])<ans.fi){ ff=1; } } if(flag[y]&&ff){ query(y,p,kd+1); } } int main(){ int t; scanf("%d",&t); int n,m; while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=0;j<3;j++){ scanf("%d",&data[i].g[j]); } data[i].id=i; } build(1,n,1,0); while(m--){ node p; for(int i=0;i<3;++i){ scanf("%d",&p.g[i]); } ans.fi=-1; query(1,p,0); printf("%d %d %d ",ans.se.g[0],ans.se.g[1],ans.se.g[2]); } } }