Range Search (kD Tree)
The range search problem consists of a set of attributed records S to determine which records from Sintersect with a given range.
For n points on a plane, report a set of points which are within in a given range. Note that you do not need to consider insert and delete operations for the set.
Input
n x0 y0 x1 y1 : xn竏�1 yn竏�1 q sx0 tx0 sy0 ty0 sx1 tx1 sy1 ty1 : sxq竏�1 txq竏�1 syq竏�1 tyq竏�1
The first integer n is the number of points. In the following n lines, the coordinate of the i-th point is given by two integers xi and yi.
The next integer q is the number of queries. In the following q lines, each query is given by four integers,sxi, txi, syi, tyi.
Output
For each query, report IDs of points such that sxi ≤ x ≤ txi and syi ≤ y ≤ tyi. The IDs should be reported in ascending order. Print an ID in a line, and print a blank line at the end of output for the each query.
Constraints
- 0 ≤ n ≤ 500,000
- 0 ≤ q ≤ 20,000
- -1,000,000,000 ≤ x, y, sx, tx, sy, ty ≤ 1,000,000,000
- sx ≤ tx
- sy ≤ ty
- For each query, the number of points which are within the range is less than or equal to 100.
Sample Input 1
6 2 1 2 2 4 2 6 2 3 3 5 4 2 2 4 0 4 4 10 2 5
Sample Output 1
0 1 2 4 2 3 5
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 using namespace std; 5 6 inline int next(void) { 7 register int ret = 0; 8 register int neg = false; 9 register int bit = getchar(); 10 for (; bit < '0'; bit = getchar()) 11 if (bit == '-')neg ^= true; 12 for (; bit >= '0'; bit = getchar()) 13 ret = ret * 10 + bit - '0'; 14 return neg ? -ret : ret; 15 } 16 17 int n, m; 18 19 int root; 20 int cmpk; 21 22 struct node { 23 int id; 24 int pos[2]; 25 int son[2]; 26 int min[2]; 27 int max[2]; 28 inline friend bool operator < 29 (const node &a, const node &b) { 30 return a.pos[cmpk] < b.pos[cmpk]; 31 } 32 }tree[500005]; 33 34 inline void update(int t) { 35 for (int k = 0; k < 2; ++k) { 36 tree[t].min[k] = tree[t].max[k] = tree[t].pos[k]; 37 for (int i = 0, s; i < 2; ++i)if (s = tree[t].son[i]) { 38 if (tree[t].min[k] > tree[s].min[k]) 39 tree[t].min[k] = tree[s].min[k]; 40 if (tree[t].max[k] < tree[s].max[k]) 41 tree[t].max[k] = tree[s].max[k]; 42 } 43 } 44 } 45 46 int build(int l, int r, int k) { 47 int d = (l + r) / 2; cmpk = k; 48 nth_element(tree + l, tree + d, tree + r + 1); 49 tree[d].son[0] = l == d ? 0 : build(l, d - 1, k ^ 1); 50 tree[d].son[1] = r == d ? 0 : build(d + 1, r, k ^ 1); 51 return update(d), d; 52 } 53 54 inline void build(void) { 55 for (int i = 1; i <= n; ++i) { 56 tree[i].id = i - 1; 57 tree[i].pos[0] = next(); 58 tree[i].pos[1] = next(); 59 } 60 root = build(1, n, 0); 61 } 62 63 int st[2], ed[2], ans[500005], tot = 0; 64 65 inline bool judge(const node &t) { 66 return t.pos[0] >= st[0] 67 && t.pos[0] <= ed[0] 68 && t.pos[1] >= st[1] 69 && t.pos[1] <= ed[1]; 70 } 71 72 inline bool check(const node &t) { 73 return t.min[0] <= ed[0] 74 && t.max[0] >= st[0] 75 && t.min[1] <= ed[1] 76 && t.max[1] >= st[1]; 77 } 78 79 void query(int t) { 80 if (judge(tree[t]))ans[tot++] = tree[t].id; 81 if (tree[t].son[0] && check(tree[tree[t].son[0]]))query(tree[t].son[0]); 82 if (tree[t].son[1] && check(tree[tree[t].son[1]]))query(tree[t].son[1]); 83 } 84 85 inline void query(void) { 86 for (int i = 0; i < m; ++i, tot = 0) { 87 st[0] = next(); 88 ed[0] = next(); 89 st[1] = next(); 90 ed[1] = next(); 91 tot = 0; 92 query(root); 93 sort(ans, ans + tot); 94 for (int j = 0; j < tot; ++j) 95 printf("%d ", ans[j]); 96 puts(""); 97 } 98 } 99 100 signed main(void) { 101 n = next(); build(); 102 m = next(); query(); 103 //system("pause"); 104 }
@Author: YouSiki