【BZOJ】【2626】JZPFAR

KD-Tree



  0.0找第k大……

  裸KD-Tree……跟之前那道找最近的k个点大同小异

  一开始理解错:第K大是第K远……不是第K近……(Tunix你个sb

  感觉容易出错的是0号点= =边界情况需要仔细处理……根据题意而定的,比如这题就必须将0号点的距离设置成最近……比如-2……(因为我一开始向堆里加的占位点的距离是-1

  1 /**************************************************************
  2     Problem: 2626
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:12956 ms
  7     Memory:4796 kb
  8 ****************************************************************/
  9
 10 //BZOJ 2626
 11 #include<queue>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 #define sqr(x) (x)*(x)
 22 using namespace std;
 23 typedef long long LL;
 24 inline int getint(){
 25     int r=1,v=0; char ch=getchar();
 26     for(;!isdigit(ch);ch=getchar()) if (ch==‘-‘) r=-1;
 27     for(; isdigit(ch);ch=getchar()) v=v*10-‘0‘+ch;
 28     return r*v;
 29 }
 30 const int N=100010,INF=1e9;
 31 /*******************template********************/
 32 int n,m,root,D;
 33 struct Poi{
 34     int d[2],mn[2],mx[2],l,r,num;
 35     int& operator [] (int x){return d[x];}
 36     void read(){d[0]=getint();d[1]=getint();}
 37 }t[N],now;
 38
 39 bool operator < (Poi a,Poi b) {return a[D]<b[D];}
 40 struct node{
 41     LL dis;int num;
 42     node(LL d=0,int n=0):dis(d),num(n){}
 43 };
 44 bool operator < (const node &a,const node &b){
 45     return a.dis>b.dis || (a.dis==b.dis && a.num<b.num);
 46 }
 47 #define L t[o].l
 48 #define R t[o].r
 49 #define mid (l+r>>1)
 50 void Push_up(int o){
 51     F(i,0,1){
 52         t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i]));
 53         t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i]));
 54     }
 55 }
 56 int build(int l,int r,int dir){
 57     D=dir;
 58     nth_element(t+l,t+mid,t+r+1);
 59     int o=mid;
 60     F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
 61     if (l<mid) L=build(l,mid-1,dir^1);
 62     if (r>mid) R=build(mid+1,r,dir^1);
 63     Push_up(o);
 64     return o;
 65 }
 66
 67 inline LL dis(Poi a,Poi b){return (LL)sqr(a[0]-b[0])+(LL)sqr(a[1]-b[1]);}
 68 inline LL getdis(int o){
 69     if (!o) return -2;
 70     LL ans=0;
 71     F(i,0,1)
 72         ans+=max((LL)sqr(t[o].mx[i]-now[i]),(LL)sqr(t[o].mn[i]-now[i]));
 73     return ans;
 74 }
 75 priority_queue<node>Q;
 76
 77 void query(int o){
 78     if (!o) return;
 79     LL dl=getdis(L),dr=getdis(R),d0=dis(t[o],now);
 80     if (d0>Q.top().dis || (d0==Q.top().dis && t[o].num<Q.top().num)){
 81         Q.pop(); Q.push(node(d0,t[o].num));
 82     }
 83     if (dl>dr){
 84         if (dl>=Q.top().dis) query(L);
 85         if (dr>=Q.top().dis) query(R);
 86     }else{
 87         if (dr>=Q.top().dis) query(R);
 88         if (dl>=Q.top().dis) query(L);
 89     }
 90 }
 91
 92 int main(){
 93 #ifndef ONLINE_JUDGE
 94     freopen("2626.in","r",stdin);
 95     freopen("2626.out","w",stdout);
 96 #endif
 97     F(i,0,1) t[0].mn[i]=INF,t[0].mx[i]=-INF;
 98     n=getint();
 99     F(i,1,n) t[i].read(),t[i].num=i;
100     root=build(1,n,1);
101     int T=getint();
102     while(T--){
103         now.read(); int k=getint();
104 //      printf("%d %d %d\n",now[0],now[1],k);
105         while(!Q.empty()) Q.pop();
106         F(i,1,k) Q.push(node(-1,0));
107         query(root);
108         printf("%d\n",Q.top().num);
109 //      printf("Q.size()=%d\n",Q.size());
110 //      F(i,1,k)
111 //          printf("%d -- %lld %lld\n",i,Q.top().dis,Q.top().num),Q.pop();
112 //      puts("");
113     }
114     return 0;
115 }

2626: JZPFAR

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 665  Solved: 248
[Submit][Status][Discuss]

Description

  平面上有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

Sample Output

3
1
1

数据规模和约定
  50%的数据中,n个点的坐标在某范围内随机分布。
  100%的数据中,n<=10^5, m<=10^4, 1<=k<=20,所有点(包括询问的点)的坐标满足绝对值<=10^9,n个点中任意两点坐标不同,m个询问的点的坐标在某范围内随机分布。

HINT

Source

[Submit][Status][Discuss]

时间: 2024-10-27 06:25:15

【BZOJ】【2626】JZPFAR的相关文章

P2433 - 【BZOJ 3262三维偏序】陌上花开------三维偏序

P2433 - [BZOJ 3262三维偏序]陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb.显然,两朵花可能有同样的属性.需要统计出评出每个等级的花的数量. Input 第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,

【BZOJ做题记录】07.07~?

在NOI一周前重开一个坑 最后更新时间:7.07 11:26 7.06 下午做的几道CQOI题: BZOJ1257: [CQOI2007]余数之和sum:把k mod i写成k-k/i*i然后分段求后面的部分就好了 BZOJ1258: [CQOI2007]三角形tri:在草稿纸上按照位置和边找一下规律就好了 BZOJ1260: [CQOI2007]涂色paint:简单的区间DP BZOJ1303: [CQOI2009]中位数图:小于中位数的改为-1大于的改为1,算一算前缀和然后哈希一下乘一乘就好

【BZOJ 2820】 YY的GCD

2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 807  Solved: 404 [Submit][Status] Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 kAc这种傻×必然不会了,于是向你来请教-- 多组输入 Input 第一行一个整数T 表述数据组数 接下来T行,每行两个正整数,表示

【BZOJ】3319: 黑白树

http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种:1.查询u到根的第一条黑边的编号.2.将u到v的路径全部染成黑色 #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream>

【bzoj】4538: [Hnoi2016]网络

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4538 维护一个数据结构支持对于一颗树的操作,需要支持: 1.对于树上的一条路径上的每个点上放一个值. 2.撤销某次操作的路劲放. 3.查询除了经过这个点的路径的最大值. 往一个路径上丢值相当于往不经过条路径的所有点上丢值. 用一个树链剖分即可维护,对于操作区间取反. 直接查询单点最大值即可. 为了维护单点最大值,线段树中的每一个点对应两个堆,用于维护插入誉删除. 防止爆空间,所以标记永久

【BZOJ】【1089】【SCOI2003】严格n元树

高精度/递推 Orz Hzwer…… 然而我想多了…… 理解以后感觉黄学长的递推好精妙啊 顺便学到了一份高精度的板子= =233 引用下题解: f[i]=f[i-1]^n+1 ans=f[d]-f[d-1] 然后加个高精度... 话说这个数据范围是虚的吧... 极限数据根本不会做.. 1 /************************************************************** 2 Problem: 1089 3 User: Tunix 4 Language:

【BZOJ】【1050】【HAOI2006】旅行comf

枚举/暴力/Kruskal orz……我sb了……其实是sb题<_< 有一道题问的是最小极差生成树……(不记得是什么名字了,就是求最大边权与最小边权差最小的生成树)做法是枚举最小边,然后kruskal找最大边 这题同理,因为$m\leq 5000$,所以$m^2$的算法即可…… 1 /************************************************************** 2 Problem: 1050 3 User: Tunix 4 Language: C

【BZOJ】【1038】【ZJOI2008】瞭望塔

计算几何/半平面交 说是半平面交,实际上只是维护了个下凸壳而已……同1007水平可见直线 对于每条线段,能看到这条线段的点都在这条线段的“上方”,那么对所有n-1条线段求一个可视区域的交,就是求一个半平面交……(好扯) 一开始我想的是:直接找到这个下凸壳的最低点,它的y值就是答案辣-但是明显不对>_>这题让求的是塔的最低高度……不光要考虑塔顶,还要看塔底的啊! 那么我们怎么找呢?我们可以发现:随着x的变化,塔高(就是地面到凸壳的竖直距离,y坐标之差)是一个分段函数,分段点就是地面的折点以及凸壳

【BZOJ】【1009】 【HNOI2008】GT考试

DP/KMP/矩阵乘法 好神的题啊……跪了跪了 $n\leq 10^9$是什么鬼……我们还是先不要考虑这个鬼畜的玩意了>_> 用类似数位DP的思路,我们可以想到一个DP方程:$f[i][j]$表示前 i 位数字,它的最后 j 位与不吉利串匹配的方案数,显然有$ans=\sum_{i=0}^x f[n][i]$ 然后就是转移的问题了= =那么依旧按照数位DP的想法(其实是硬扯到那的吧……怎么理解都可以,重点是明白转移方程)可以想到:从 i 转移到 i+1,有10种方案,其中一种会使得匹配长度+1

【BZOJ】1821: [JSOI2010]Group 部落划分 Group(最小生成树+贪心)

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1821 这题裸题. 本题要求最短距离最长,很明显,我们排序. 这里存在贪心,即我们把边权最小的全分给n个部落的内部,然后剩下的边最小的就是答案. 将边权较小的边分给k个部落,用并查集生成最小树,使得内部的边总是小于连到外部的边.然后分剩下k个点即可,剩下的k个点的那条边一定是部落之间最小的且最长的边. #include <cstdio> #include <cstring> #