分析:题意是给一个二维平面,平面有一些点给出座标x,y和高度h,然后m个询问,每次询问 小于等于x,y这个点的点集中h第k小的点。我们观察到由于题目中k很小只有10,所以我们可以用线段树维护y轴,把点转换成扫描线,从左到右扫过,遇到建筑则更新线段树,遇到query则查询。每个节点,我们只需要维护区间的前10小的点的高度即可。然后更新点的时候直接按照大小在区间插入即可,然后查询的时候用一个大顶堆维护K个最小值即可,当然,由于点的座标很大,需要对点离散化。值得一提的是,没必要要把查询的点的y座标和平面上点的y座标一起离散化成线段树的区间维护,直接代入查询即可。这样做的话时间从750MS提到了650MS,因为对空间的需求和递归的深度都会低很多。详见代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
struct Point{
int x, y, h, type, id;//0为建筑 1为查询点
}p[60006];
int ans[30003];
struct Tnode{
int a[11];
int num;
}node[30006<<2];
int yy[30006];
priority_queue<int> q;
bool operator<(const Point &a, const Point &b){
return a.x < b.x || a.x == b.x && a.y < b.y || a.x == b.x && a.y == b.y && a.type < b.type;
}
void inline _insert(int *first, int *last, int key){
while(last > first && *(last-1) > key) {*last = *(last-1);last--;}
*last = key;
}
void update(int rt, int l, int r, int y, int key){
_insert(node[rt].a, node[rt].a+node[rt].num, key);
if(node[rt].num < 10) node[rt].num++;
if(l != r){
int mid = l + r >> 1;
if(y <= yy[mid]) update(rt<<1, l, mid, y, key);
else update(rt<<1|1, mid+1, r, y, key);
}
}
inline void add_queue(int rt, int k){
for(int i = 0; i < node[rt].num; i++){
q.push(node[rt].a[i]);
if(q.size() > k) q.pop();
}
}
void query(int rt, int l, int r, int y, int k){
if(y < yy[l]) return;
if(y >= yy[r]){
add_queue(rt, k);
return;
}
int mid = l + r >> 1;
if(y <= yy[mid]) query(rt<<1, l, mid, y, k);
else{
query(rt<<1, l, mid, y, k);
query(rt<<1|1, mid+1, r, y, k);
}
}
int main(){
int n, m;
while(scanf("%d%d", &n, &m) == 2){
memset(node, 0, sizeof(node));
for(int i = 0; i < n; i++){
scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].h);
p[i].type = 0;
yy[i] = p[i].y;
}
for(int i = n; i < m + n; i++){
scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].h);
p[i].type = 1;
p[i].id = i - n;
}
sort(p, p + n + m);
sort(yy, yy + n);
int mm = unique(yy, yy + n) - yy;
for(int i = 0; i < m + n; i++){
if(p[i].type == 0){
update(1, 0, mm-1, p[i].y, p[i].h);
}else{
while(!q.empty()) q.pop();
query(1, 0, mm-1, p[i].y, p[i].h);
if(q.size() == p[i].h) ans[p[i].id] = q.top();
else ans[p[i].id] = -1;
}
}
for(int i = 0; i < m; i++){
printf("%d\n", ans[i]);
}
}
return 0;
}