记录编号 225992 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]JZPFAR 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 14.691 s
提交时间 2016-02-17 18:48:29 内存使用 1.45 MiB
显示代码纯文本
#define null NULL
#define maxn 100010ul

#define ll long long

#include <queue>
#include <stdio.h>
#include <algorithm>

struct Point{
	int d[3];
	int& operator [](const int x){return d[x];}
}sp[maxn],cp;

struct res{
	ll dis;int id;
	friend bool operator < (res a,res b){return a.dis>b.dis||(a.dis==b.dis&&a.id<b.id);}
};

int n,q,cur,K;
const ll inf=1e16;

inline ll sqr(ll x){return x*x;}
inline ll dis(Point x,Point y){return sqr((ll)x[0]-(ll)y[0])+sqr((ll)x[1]-(ll)y[1]);}
inline bool cmp(Point a,Point b){return a[cur]<b[cur]||(a[cur]==b[cur]&&a[cur^1]<b[cur^1]);}
inline ll Min(ll a,ll b){return a<b?a:b;}
inline ll Max(ll a,ll b){return a>b?a:b;}

struct node{
	node *left,*right;
	Point point;
	int min_limit[2],max_limit[2];
	node(Point &x){
		point=x;
		left=right=null;
		min_limit[0]=max_limit[0]=x[0];
		min_limit[1]=max_limit[1]=x[1];
		return;
	}
	inline void update(node *&x){
		if(x==null) return;
		for(int i=0;i<2;i++) min_limit[i]=Min(min_limit[i],x->min_limit[i]);
		for(int i=0;i<2;i++) max_limit[i]=Max(max_limit[i],x->max_limit[i]);
		return;
	}
	inline ll max_dis(){
		ll res=0;
		res=Max(res,dis((Point){min_limit[0],min_limit[1]},cp));
		res=Max(res,dis((Point){min_limit[0],max_limit[1]},cp));
		res=Max(res,dis((Point){max_limit[0],min_limit[1]},cp));
		res=Max(res,dis((Point){max_limit[0],max_limit[1]},cp));
		return res;
	}
}*root;

std::priority_queue<res> que;

inline void build(node *&rt,int l,int r,int d){
	if(l>r) return;
	int mid=(l+r)>>1;
	cur=d,std::nth_element(sp+l+1,sp+mid+1,sp+r+1,cmp);
	rt=new node(sp[mid]);
	build(rt->left,l,mid-1,d^1);
	build(rt->right,mid+1,r,d^1);
	rt->update(rt->left);
	rt->update(rt->right);
	return;
}

inline void ask(node *rt){
	if(rt==null) return;
	if(que.size()==K&&rt->max_dis()<que.top().dis) return;
	res ret=(res){dis(cp,rt->point),rt->point[2]};
	if(que.size()<K) que.push(ret);
	else if(ret<que.top()) que.pop(),que.push(ret);
	ll disL=rt->left!=null?rt->left->max_dis():inf;
	ll disR=rt->right!=null?rt->right->max_dis():inf;
	if(disL>disR){
        ask(rt->left);
        if(disR>=que.top().dis) ask(rt->right);
	}
	else{
        ask(rt->right);
        if(disL>=que.top().dis) ask(rt->left);
	}
	return;
}

inline int in(){
	int x=0,c=getchar();bool flag=false;
	while(c<'0'||c>'9'){
        if(c=='-') flag=true;
		c=getchar();
	}
	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	if(flag) return -x;
	return x;
}

inline int query(Point tmp){
	while(!que.empty()) que.pop();
	cp=tmp;ask(root);
	return que.top().id;
}

int main(){
	freopen("jzpfar.in","r",stdin);
	freopen("jzpfar.out","w",stdout);
 	n=in();
	for(int i=1;i<=n;i++) sp[i][0]=in(),sp[i][1]=in(),sp[i][2]=i;
	build(root,1,n,0);q=in();
	for(int i=1,x,y;i<=q;i++) x=in(),y=in(),K=in(),printf("%d\n",query((Point){x,y,0}));
	return 0;
}