• AOJ DSL_2_C Range Search (kD Tree)


    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呢,( ﹁ ﹁ ) ~→
     
      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

  • 相关阅读:
    应用实例:用户登录(2009.10.23)
    ASP.NET学习笔记:服务器控件 (2009.11.9)
    小实例:模拟电话簿
    用Iframe实现左边TreeView导航,右边显示相应内容的布局
    HTML&CSS&JaveScript学习笔记(2009.11.19)
    C#中问号(?)的用法
    GridView的简单分页等
    GridView正反双向排序
    代码理解(2009.11.20)
    ASP.NET学习笔记:数据库操作 (2009.11.10)
  • 原文地址:https://www.cnblogs.com/yousiki/p/6188289.html
Copyright © 2020-2023  润新知