K-short Problem
K-short Problem
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 693 Accepted Submission(s): 217
Problem Description
In the view of a satellite, you can see lots of tall buildings in the city, and we assume that the city's border is flat. Now you have observed n tall buildings in the city and recorded their position and height. Due to some mysterious reasons, you need to answer a series of queries. Each query will give you a position(x, y) and k, then you have to find out the k-th shortest building in set{(x,y)|x≤X,y≤Y}.
Input
Multiple test cases.For each test case, the first line will contain two integers n and m(0<n≤30000,0≤m≤30000), which represents the amount of buildings and amount of queries. Then n lines follow, contains three integers x,y,h(−1E9≤x,y≤1E9,0≤h≤1E9) indicate the building's position and height in each line. Then there are m lines, each with three integers x,y,k(−1E9≤x,y≤1E9,1≤k≤10) used for query.
Output
For each test case, if the k-th shortest building exists, output its height in 1 line, otherwise print "-1" (without quotes).
Sample Input
5 2
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
0 0 1
6 3 2
Sample Output
-1
2
#include <bits/stdc++.h> typedef long long ll; using namespace std; const int maxn = 6e4 + 10; struct answer { int tot; int rk[16]; answer() { tot = 0; } inline void insert(int val) { if (tot <= 10) { rk[++tot] = val; } else if (val < rk[tot]) { rk[tot] = val; } sort(rk + 1, rk + 1 + tot); } } ans[maxn<<2]; struct atom { int x, y, height, id; bool operator<(const atom &cur) const { if (x != cur.x)return x < cur.x; if (y != cur.y)return y < cur.y; return id < cur.id; } } o[maxn<<1]; int n, m, cnt; int ls[maxn<<2], rs[maxn<<2]; vector<int> re, lsh; inline answer merge(answer s, answer t) { answer cur; int ss = 1, tt = 1; while ((ss <= s.tot || tt <= t.tot) && cur.tot <= 10) { if (tt > t.tot || (ss <= s.tot && s.rk[ss] < t.rk[tt])) { cur.rk[++cur.tot] = s.rk[ss++]; } else { cur.rk[++cur.tot] = t.rk[tt++]; } } return cur; } inline void build(int rt, int l, int r) { ls[rt] = l; rs[rt] = r; if (l == r) { ans[rt].tot = 0; return; } int mid = l + r >> 1; build(rt << 1, l, mid); build(rt << 1 | 1, mid + 1, r); ans[rt] = merge(ans[rt << 1], ans[rt << 1 | 1]); } inline void insert(int rt, int pos, int val) { if (ls[rt] == pos && rs[rt] == pos) { ans[rt].insert(val); return; } int mid = ls[rt] + rs[rt] >> 1; if (pos <= mid) { insert(rt << 1, pos, val); } else { insert(rt << 1 | 1, pos, val); } ans[rt] = merge(ans[rt << 1], ans[rt << 1 | 1]); } inline void init() { re.clear(); lsh.clear(); int x, y, height; for (register int i = 1; i <= n; ++i) { scanf("%d%d%d", &x, &y, &height); // x=rand()%100; // y=rand()%100; // height=rand()%8; re.emplace_back(y); o[i] = (atom) {x, y, height, 0}; } for (register int i = 1; i <= m; ++i) { scanf("%d%d%d", &x, &y, &height); // x=rand()%100; // y=rand()%100; // height=rand()%8; re.emplace_back(y); o[i + n] = (atom) {x, y, height, i}; } sort(re.begin(), re.end()); lsh.emplace_back(re[0]); for (register int i = 1; i < re.size(); ++i) { if (re[i] != re[i - 1]) { lsh.emplace_back(re[i]); } } // for (register int i = 0; i < re.size(); ++i) { // printf("%d ", re[i]); // } // printf("\n"); build(1, 0, lsh.size()-1); } inline answer query(int rt, int l, int r) { if (l <= ls[rt] && r >= rs[rt]) { return ans[rt]; } int mid = (ls[rt] + rs[rt]) >> 1; answer cur; if (l <= mid) { cur = merge(cur, query(rt << 1, l, r)); } if (r > mid) { cur = merge(cur, query(rt << 1 | 1, l, r)); } return cur; } int e[maxn]; inline int getid(int se) { return lower_bound(lsh.begin(), lsh.end(), se) - lsh.begin(); } inline void solve() { sort(o + 1, o + 1 + n + m); for (register int i = 1; i <= n + m; ++i) { if (o[i].id) { answer res = query(1, 0, getid(o[i].y)); int K_th = o[i].height; if (K_th > res.tot) { e[o[i].id] = -1; } else { e[o[i].id] = res.rk[K_th]; } } else { insert(1, getid(o[i].y), o[i].height); } } } int main() { #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif while (scanf("%d%d", &n, &m) == 2) { init(); solve(); for (register int i = 1; i <= m; ++i) { printf("%d\n", e[i]); } } return 0; }