分析:題意是給一個二維平面,平面有一些點給出座標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;
}