您的位置:首页 > 其它

AOJ DSL_2_C Range Search (kD Tree)

2016-12-16 20:24 337 查看

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


虽然说是KD-Tree模板题,但是貌似怎么做都可以;当然拿来练习KD-Tree还是十分不错的。于是压了压常数就在AOJ上打榜了,谁叫JP人总喜欢用cin和STL呢,( ﹁ ﹁ ) ~→

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

inline int next(void) {
register int ret = 0;
register int neg = false;
register int bit = getchar();
for (; bit < '0'; bit = getchar())
if (bit == '-')neg ^= true;
for (; bit >= '0'; bit = getchar())
ret = ret * 10 + bit - '0';
return neg ? -ret : ret;
}

int n, m;

int root;
int cmpk;

struct node {
int id;
int pos[2];
int son[2];
int min[2];
int max[2];
inline friend bool operator <
(const node &a, const node &b) {
return a.pos[cmpk] < b.pos[cmpk];
}
}tree[500005];

inline void update(int t) {
for (int k = 0; k < 2; ++k) {
tree[t].min[k] = tree[t].max[k] = tree[t].pos[k];
for (int i = 0, s; i < 2; ++i)if (s = tree[t].son[i]) {
if (tree[t].min[k] > tree[s].min[k])
tree[t].min[k] = tree[s].min[k];
if (tree[t].max[k] < tree[s].max[k])
tree[t].max[k] = tree[s].max[k];
}
}
}

int build(int l, int r, int k) {
int d = (l + r) / 2; cmpk = k;
nth_element(tree + l, tree + d, tree + r + 1);
tree[d].son[0] = l == d ? 0 : build(l, d - 1, k ^ 1);
tree[d].son[1] = r == d ? 0 : build(d + 1, r, k ^ 1);
return update(d), d;
}

inline void build(void) {
for (int i = 1; i <= n; ++i) {
tree[i].id = i - 1;
tree[i].pos[0] = next();
tree[i].pos[1] = next();
}
root = build(1, n, 0);
}

int st[2], ed[2], ans[500005], tot = 0;

inline bool judge(const node &t) {
return t.pos[0] >= st[0]
&& t.pos[0] <= ed[0]
&& t.pos[1] >= st[1]
&& t.pos[1] <= ed[1];
}

inline bool check(const node &t) {
return t.min[0] <= ed[0]
&& t.max[0] >= st[0]
&& t.min[1] <= ed[1]
&& t.max[1] >= st[1];
}

void query(int t) {
if (judge(tree[t]))ans[tot++] = tree[t].id;
if (tree[t].son[0] && check(tree[tree[t].son[0]]))query(tree[t].son[0]);
if (tree[t].son[1] && check(tree[tree[t].son[1]]))query(tree[t].son[1]);
}

inline void query(void) {
for (int i = 0; i < m; ++i, tot = 0) {
st[0] = next();
ed[0] = next();
st[1] = next();
ed[1] = next();
tot = 0;
query(root);
sort(ans, ans + tot);
for (int j = 0; j < tot; ++j)
printf("%d\n", ans[j]);
puts("");
}
}

signed main(void) {
n = next(); build();
m = next(); query();
//system("pause");
}


@Author: YouSiki
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: