AOJ DSL_2_C kD tree

Prob.

给二维平面的一些点,求某个矩形内所有点的下标。

Sol.

k-d 裸题。
有空再写教程吧……这次就算了。

Code(160ms 22284kB)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
template<class T> 
inline void read(T& x)
{
    char c = getchar(); T p = 1, n = 0;
    while(c < '0' || c > '9'){if(c == '-') p = -1; c = getchar();}
    while(c >= '0' && c <= '9'){n = n * 10 + c - '0'; c = getchar();}
    x = p * n;
}
template<class T, class U>
inline void read(T& x, U& y){read(x), read(y);}
template<class T, class U, class V>
inline void read(T& x, U& y, V& z){read(x), read(y), read(z);}
const int maxn = 5e5 + 100;
int D; int n, root; 
struct Point
{
    int d[2], l, r, num;
    Point(){l = 0, r = 0;}
    int& operator[](int i){return d[i];}
    bool operator<(const Point& p)const{return d[D] < p.d[D];}
} P[maxn], t[maxn];
int tc = 1;
int build(int L = 0, int R = n - 1, int d = 0)
{
    int M = (L + R) >> 1;
    D = d;
    nth_element(P + L, P + M, P + R + 1);
    int o = tc++;
    t[o] = P[M];
    if(L < M) t[o].l = build(L, M - 1, d ^ 1);
    if(M < R) t[o].r = build(M + 1, R, d ^ 1);
    return o;
}
int sx, tx, sy, ty; vector<int> ans;
void find(int o = root, int d = 0)
{
    if(sx <= t[o].d[0] && t[o].d[0] <= tx && sy <= t[o].d[1] && t[o].d[1] <= ty)
        ans.push_back(t[o].num);
    if(d == 0)
    {
        if(t[o].l && sx <= t[o][0]) find(t[o].l, d ^ 1);
        if(t[o].r && t[o][0] <= tx) find(t[o].r, d ^ 1);
    }
    else
    {
        if(t[o].l && sy <= t[o][1]) find(t[o].l, d ^ 1);
        if(t[o].r && t[o][1] <= ty) find(t[o].r, d ^ 1);
    }
}
int main()
{
    read(n);
    for(int i = 0; i < n; ++i) read(P[i][0], P[i][1]), P[i].num = i;
    root = build();
    int q; read(q);
    while(q--)
    {
        ans.clear();
        read(sx, tx), read(sy, ty);
        find();
        sort(ans.begin(), ans.end());
        for(int i = 0; i < ans.size(); ++i) printf("%d\n", ans[i]);
        puts("");
    }
    return 0;
}

标签: none

添加新评论