Skip to content

Commit 7ab3045

Browse files
committed
KD-Tree
1 parent 066fb49 commit 7ab3045

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

K-Dimensional-Tree.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Problem Name: SJY摆棋子
2+
// Algorithm: KD-Tree
3+
4+
#include <cstdio>
5+
#include <algorithm>
6+
7+
#define NIL 0
8+
#define INF 1000000000
9+
10+
using namespace std;
11+
12+
struct point
13+
{
14+
int co[2];
15+
point(int x = 0, int y = 0) { co[0] = x, co[1] = y; }
16+
int& operator [] (int x) { return co[x]; }
17+
const int& operator [] (int x) const { return co[x]; }
18+
}d[500010];
19+
20+
struct node
21+
{
22+
node *lch, *rch;
23+
point p;
24+
int min[2], max[2];
25+
node(point _p = point()) : lch(NIL), rch(NIL), p(_p) { /*min[0] = min[1] = INF, max[0] = max[1] = -INF;*/ }
26+
}*root;
27+
28+
inline int abs(int x)
29+
{
30+
return x < 0 ? -x : x;
31+
}
32+
33+
inline int dist(point &x, point &y)
34+
{
35+
return abs(x.co[0] - y.co[0]) + abs(x.co[1] - y.co[1]);
36+
}
37+
38+
int _d_;
39+
inline bool _point_cmp_(const point &x, const point &y)
40+
{
41+
if (x[_d_] == y[_d_]) return x[_d_ ^ 1] < y[_d_ ^ 1];
42+
return x[_d_] < y[_d_];
43+
}
44+
45+
inline void update(node *u)
46+
{
47+
if (u->lch != NIL)
48+
{
49+
u->min[0] = min(u->min[0], u->lch->min[0]);
50+
u->min[1] = min(u->min[1], u->lch->min[1]);
51+
u->max[0] = max(u->max[0], u->lch->max[0]);
52+
u->max[1] = max(u->max[1], u->lch->max[1]);
53+
}
54+
if (u->rch != NIL)
55+
{
56+
u->min[0] = min(u->min[0], u->rch->min[0]);
57+
u->min[1] = min(u->min[1], u->rch->min[1]);
58+
u->max[0] = max(u->max[0], u->rch->max[0]);
59+
u->max[1] = max(u->max[1], u->rch->max[1]);
60+
}
61+
}
62+
63+
void build(node *&u, int l, int r, int dim)
64+
{
65+
if (l == r)
66+
{
67+
u = new node(d[l]);
68+
u->min[0] = u->max[0] = d[l][0];
69+
u->min[1] = u->max[1] = d[l][1];
70+
}
71+
else if (l < r)
72+
{
73+
int mid = (l + r) >> 1;
74+
_d_ = dim;
75+
nth_element(d + l, d + mid, d + r + 1, _point_cmp_);
76+
u = new node(d[mid]);
77+
u->min[0] = u->max[0] = d[mid][0];
78+
u->min[1] = u->max[1] = d[mid][1];
79+
build(u->lch, l, mid - 1, dim ^ 1);
80+
build(u->rch, mid + 1, r, dim ^ 1);
81+
update(u);
82+
}
83+
}
84+
85+
void insert(node *&u, point p, int dim)
86+
{
87+
if (u == NIL)
88+
{
89+
u = new node(p);
90+
u->min[0] = u->max[0] = p[0];
91+
u->min[1] = u->max[1] = p[1];
92+
return;
93+
}
94+
if (p[dim] <= u->p[dim]) insert(u->lch, p, dim ^ 1);
95+
else insert(u->rch, p, dim ^ 1);
96+
update(u);
97+
}
98+
99+
int get_dis(point p, node *u)
100+
{
101+
int res = 0;
102+
if (p[0] < u->min[0]) res += u->min[0] - p[0];
103+
if (p[0] > u->max[0]) res += p[0] - u->max[0];
104+
if (p[1] < u->min[1]) res += u->min[1] - p[1];
105+
if (p[1] > u->max[1]) res += p[1] - u->max[1];
106+
return res;
107+
}
108+
109+
int mindis;
110+
void find(node *u, point p, int dim)
111+
{
112+
if (u == NIL) return;
113+
int dis = dist(p, u->p);
114+
if (dis < mindis) mindis = dis;
115+
int dl = INF, dr = INF;
116+
if (u->lch != NIL) dl = get_dis(p, u->lch);
117+
if (u->rch != NIL) dr = get_dis(p, u->rch);
118+
if (dl < dr)
119+
{
120+
if (dl < mindis) find(u->lch, p, dim ^ 1);
121+
if (dr < mindis) find(u->rch, p, dim ^ 1);
122+
}
123+
else
124+
{
125+
if (dr < mindis) find(u->rch, p, dim ^ 1);
126+
if (dl < mindis) find(u->lch, p, dim ^ 1);
127+
}
128+
}
129+
130+
void dfs(node *u)
131+
{
132+
if (u == NIL) return;
133+
printf("dfs : (%d, %d)\n", u->p[0], u->p[1]);
134+
dfs(u->lch);
135+
dfs(u->rch);
136+
}
137+
138+
int main()
139+
{
140+
int n, m;
141+
scanf("%d%d", &n, &m);
142+
for (int i = 0; i < n; i++)
143+
{
144+
scanf("%d%d", &d[i][0], &d[i][1]);
145+
}
146+
build(root, 0, n - 1, 0);
147+
int op, x, y;
148+
while (m--)
149+
{
150+
scanf("%d%d%d", &op, &x, &y);
151+
if (op == 1)
152+
{
153+
insert(root, point(x, y), 0);
154+
}
155+
else
156+
{
157+
mindis = INF;
158+
find(root, point(x, y), 0);
159+
if (mindis < INF) printf("%d\n", mindis);
160+
else printf("INF\n");
161+
}
162+
}
163+
return 0;
164+
}

0 commit comments

Comments
 (0)