BZOJ2626: JZPFAR

BZOJ2626: JZPFARphp

BZOJ氪金無極限。。。ios

洛谷大好!ui

洛谷P2093 [國家集訓隊]JZPFARspa

題目描述

平面上有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行,每行一個整數,表示相應的詢問的答案。

 

輸入輸出樣例

輸入樣例: 
3
0 0
0 1
0 2
3
1 1 2
0 0 3
0 1 1
輸出樣例: 
3
1
1

說明

50%的數據中,n個點的座標在某範圍內隨機分佈。

100%的數據中,n<=10^5, m<=10^4, 1<=k<=20,全部點(包括詢問的點)的座標知足絕對值<=10^9,n個點中任意兩點座標不一樣,m個詢問的點的座標在某範圍內隨機分佈。


題解Here!

實際上是一道裸的$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;
}
本站公眾號
   歡迎關注本站公眾號,獲取更多信息