[国家集训队2012]JZPFAR

[国家集训队2012]JZPFAR

题目

平面上有n个点。现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号。如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大。

INPUT

第一行,一个整数n,表示点的个数。
下面n行,每行两个整数x_i, y_i,表示n个点的坐标。点的标号按照输入顺序,分别为1..n。
下面一行,一个整数m,表示询问个数。
下面m行,每行三个整数px_i, py_i, k_i,表示一个询问。

OUTPUT

m行,每行一个整数,表示相应的询问的答案。

SAMPLE

INPUT

3
0 0
0 1
0 2
3
1 1 2
0 0 3
0 1 1

OUTPUT

3
1
1

解题报告

首道K-D树

然而只是照着打了个板子QAQ

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<queue>
  6 using namespace std;
  7 typedef long long L;
  8 const L inf((L)1e16);
  9 int now,n,m,k;
 10 inline int read(){
 11     int sum(0),f(1);
 12     char ch(getchar());
 13     for(;ch<‘0‘||ch>‘9‘;ch=getchar())
 14         if(ch==‘-‘)
 15             f=-1;
 16     for(;ch>=‘0‘&&ch<=‘9‘;sum=sum*10+(ch^48),ch=getchar());
 17     return sum*f;
 18 }
 19 struct point{
 20     L a[3];
 21     inline bool operator<(const point &b)const{
 22         return a[now]<b.a[now]||(a[now]==b.a[now]&&a[now^1]<b.a[now^1]);
 23     }
 24     L &operator[](int x){
 25         return a[x];
 26     }
 27 }p[100005],cmp;
 28 struct data{
 29     L dis,id;
 30     inline bool operator<(const data &a)const{
 31         return dis==a.dis?id<a.id:dis>a.dis;
 32     }
 33 };
 34 priority_queue<data>q;
 35 inline L pf(L x){
 36     return x*x;
 37 }
 38 inline L dis(point x,point y){
 39     return pf(x[0]-y[0])+pf(x[1]-y[1]);
 40 }
 41 struct node{
 42     node *lch,*rch;
 43     point key;
 44     int mn[2],mx[2];
 45     node(point &x):key(x),lch(NULL),rch(NULL){
 46         mn[0]=mx[0]=x[0];
 47         mn[1]=mx[1]=x[1];
 48     }
 49     inline void pushup(node *x){
 50         if(x==NULL)
 51             return;
 52         mn[0]=min(mn[0],x->mn[0]),mn[1]=min(mn[1],x->mn[1]);
 53         mx[0]=max(mx[0],x->mx[0]),mx[1]=max(mx[1],x->mx[1]);
 54     }
 55     inline L cal_dis(){
 56         L ret(0);
 57         ret=max(ret,dis((point){mn[0],mn[1]},cmp));
 58         ret=max(ret,dis((point){mn[0],mx[1]},cmp));
 59         ret=max(ret,dis((point){mx[0],mn[1]},cmp));
 60         ret=max(ret,dis((point){mx[0],mx[1]},cmp));
 61         return ret;
 62     }
 63 }*root;
 64 inline void build(node *&rt,int l,int r,int d){
 65     if(l>r)
 66         return;
 67     int mid((l+r)>>1);
 68     now=d;
 69     nth_element(p+l,p+mid,p+r+1);
 70     rt=new node(p[mid]);
 71     build(rt->lch,l,mid-1,d^1);
 72     build(rt->rch,mid+1,r,d^1);
 73     rt->pushup(rt->lch);
 74     rt->pushup(rt->rch);
 75 }
 76 inline void query(node *rt){
 77     if(rt==NULL)
 78         return;
 79     if(q.size()==k&&rt->cal_dis()<q.top().dis)
 80         return;
 81     data ret((data){dis(rt->key,cmp),rt->key[2]});
 82     if(q.size()<k)
 83         q.push(ret);
 84     else
 85         if(ret<q.top())
 86             q.pop(),q.push(ret);
 87     L dis_l(rt->lch==NULL?inf:rt->lch->cal_dis());
 88     L dis_r(rt->rch==NULL?inf:rt->rch->cal_dis());
 89     if(dis_l>dis_r){
 90         query(rt->lch);
 91         if(dis_r>=q.top().dis||q.size()<k)
 92             query(rt->rch);
 93     }
 94     else{
 95         query(rt->rch);
 96         if(dis_l>=q.top().dis||q.size()<k)
 97             query(rt->lch);
 98     }
 99 }
100 inline int gg(){
101     freopen("jzpfar.in","r",stdin);
102     freopen("jzpfar.out","w",stdout);
103     n=read();
104     for(int i=1;i<=n;++i)
105         p[i][0]=read(),p[i][1]=read(),p[i][2]=i;
106     build(root,1,n,0);
107     m=read();
108     while(m--){
109         cmp[0]=read(),cmp[1]=read(),k=read();
110         while(!q.empty())
111             q.pop();
112         query(root);
113         printf("%d\n",q.top().id);
114     }
115     return 0;
116 }
117 int K(gg());
118 int main(){;}

时间: 2024-11-06 09:30:25

[国家集训队2012]JZPFAR的相关文章

[国家集训队2012]tree(陈立杰)

[国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示点数,边数和需要的白色边数.接下来E行每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色). OUTPUT 一行表示所求生成树的边权和. SAMPLE INPUT 2 2 1 0 1 1 1 0 1 2 0 OUTPUT 2 数据规模 0:V<=101,2,3:V<=

[COGS 1799][国家集训队2012]tree(伍一鸣)

Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树: * u v c:将u到v的路径上的点的权值都乘上自然数c: / u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数. Input 第一行两个整数n,q 接下来n-1行每行两个正整数u,v,

【国家集训队2012】tree(伍一鸣)

题面 传送门 Sol 这不是一道LCT模板题吗? 和线段树一样维护区间加法和乘法标记 记得要更新自己本身的权值 这种题就该一遍AC # include <bits/stdc++.h> # define RG register # define IL inline # define Fill(a, b) memset(a, b, sizeof(a)) # define Sqr(x) ((x) * (x)) # define ls ch[0][x] # define rs ch[1][x] usi

国家集训队2011 happiness

[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. [输入格式] 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学

[国家集训队2010]小Z的袜子

★★★   输入文件:hose.in   输出文件:hose.out   简单对比 时间限制:1 s   内存限制:512 MB [题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务便

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只

[补档][国家集训队2011]单选错位

题目 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案. 试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对sigma(1/ai)道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第

【BZOJ】2038: [2009国家集训队]小Z的袜子(hose)

[算法]莫队 [题解] BZOJ 2038 2009国家集训队 小Z的袜子(hose) 莫队算法 莫队--讲稿? 施工中--

cogs 1901. [国家集训队2011]数颜色

Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔.2. R P Col 把第P支画笔替换为