BZOJ氪金無極限。。。ios
洛谷大好!ui
平面上有n個點。如今有m次詢問,每次給定一個點(px, py)和一個整數k,輸出n個點中離(px, py)的距離第k大的點的標號。blog
若是有兩個(或多個)點距離(px, py)相同,那麼認爲標號較小的點距離較大。element
輸入格式:get
第一行,一個整數n,表示點的個數。it
下面n行,每行兩個整數x_i, y_i,表示n個點的座標。點的標號按照輸入順序,分別爲1..n。io
下面一行,一個整數m,表示詢問個數。class
下面m行,每行三個整數px_i, py_i, k_i,表示一個詢問。
輸出格式:
m行,每行一個整數,表示相應的詢問的答案。
50%的數據中,n個點的座標在某範圍內隨機分佈。
100%的數據中,n<=10^5, m<=10^4, 1<=k<=20,全部點(包括詢問的點)的座標知足絕對值<=10^9,n個點中任意兩點座標不一樣,m個詢問的點的座標在某範圍內隨機分佈。
實際上是一道裸的$K-D \ Tree$。
可是本蒟蒻表示並不能理解。。。
因而對着板子敲了一遍。。。
連我本身都不知道我怎麼$WA$的,又是怎麼$AC$的。。。
附代碼:
#include<iostream> #include<algorithm> #include<cstdio> #include<queue> #define MAXN 101000 #define MAX (1LL<<60) using namespace std; int n,m,root; bool sort_flag=false; struct Point{ int id; long long x,y; friend bool operator <(const Point &p,const Point &q){ if(sort_flag)return p.y<q.y; return p.x<q.x; } }point[MAXN],now; struct Tree{ Point point; long long minx,miny,maxx,maxy; int lson,rson,minid; Tree(){minid=2147483646;} }a[MAXN]; struct Heap{ int id; long long dis; friend bool operator <(const Heap &p,const Heap &q){ if(p.dis==q.dis)return p.id<q.id; return p.dis>q.dis; } }; priority_queue<Heap> heap; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } inline long long get_dis(const Point &p,const Point &q){ return (p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y); } inline void pushup(int rt){ int lson=a[rt].lson,rson=a[rt].rson; a[rt].minid=min(a[rt].point.id,min(a[lson].minid,a[rson].minid)); a[rt].maxx=max(a[rt].maxx,max(a[lson].maxx,a[rson].maxx)); a[rt].maxy=max(a[rt].maxy,max(a[lson].maxy,a[rson].maxy)); a[rt].minx=min(a[rt].minx,min(a[lson].minx,a[rson].minx)); a[rt].miny=min(a[rt].miny,min(a[lson].miny,a[rson].miny)); } void buildtree(int l,int r,int &rt,int flag){ int mid=l+r>>1; rt=mid; sort_flag=flag; nth_element(point+l,point+mid,point+r+1); a[rt].point=point[mid]; a[rt].minx=a[rt].maxx=point[mid].x; a[rt].miny=a[rt].maxy=point[mid].y; if(l<mid)buildtree(l,mid-1,a[rt].lson,flag^1); if(mid<r)buildtree(mid+1,r,a[rt].rson,flag^1); pushup(rt); } inline long long max_dis(int rt){ long long x,y; x=max(abs(now.x-a[rt].minx),abs(now.x-a[rt].maxx)); y=max(abs(now.y-a[rt].miny),abs(now.y-a[rt].maxy)); return (x*x+y*y); } void query(int rt){ int id=a[rt].point.id; long long dis=get_dis(a[rt].point,now),ldis=-MAX,rdis=-MAX; if((Heap){id,dis}<heap.top()){ heap.pop(); heap.push((Heap){id,dis}); } if(a[rt].lson)ldis=max_dis(a[rt].lson); if(a[rt].rson)rdis=max_dis(a[rt].rson); if(ldis>rdis){ if((Heap){a[a[rt].lson].minid,ldis}<heap.top())query(a[rt].lson); if((Heap){a[a[rt].rson].minid,rdis}<heap.top())query(a[rt].rson); } else{ if((Heap){a[a[rt].rson].minid,rdis}<heap.top())query(a[rt].rson); if((Heap){a[a[rt].lson].minid,ldis}<heap.top())query(a[rt].lson); } } void work(){ int k; while(m--){ while(!heap.empty())heap.pop(); now.x=read();now.y=read();k=read(); while(k--)heap.push((Heap){0,-MAX}); query(root); printf("%d\n",heap.top().id); } } void init(){ n=read(); a[0].maxx=a[0].maxy=-MAX; a[0].minx=a[0].miny=MAX; for(int i=1;i<=n;i++){ point[i].x=read();point[i].y=read(); point[i].id=i; } m=read(); buildtree(1,n,root,0); } int main(){ init(); work(); return 0; }