大概就是个复杂度对的暴力做法,在你不想写二维线段树等的时候优秀的替代品。

优点:思路简单,代码好写。

他大概有两种用法(虽然差不多)。

 

在平面坐标系中干一些事情:

例如最常规的平面最近最远点,不管是欧几里得距离还是曼哈顿距离,本质上都是一样的。

利用不同维度的尽量平均的分割,再在询问时剪枝。

这里给出一个曼哈顿距离上的最近最远距离的版本,可供参考:

 1 namespace KD {
 2     int Rt, lc[N], rc[N], u[N], d[N], l[N], r[N];
 3     inline void Merge(int x, int y) {
 4         u[x] = std::max(u[x], u[y]);
 5         d[x] = std::min(d[x], d[y]);
 6         l[x] = std::min(l[x], l[y]);
 7         r[x] = std::max(r[x], r[y]);
 8     }
 9     inline void Up(int t) {
10         l[t] = r[t] = p[t].v[0];
11         u[t] = d[t] = p[t].v[1];
12         if (lc[t]) Merge(t, lc[t]);
13         if (rc[t]) Merge(t, rc[t]);
14     }
15     int Build(int l, int r, int dep) {
16         if (l >= r) {
17             if (l == r) Up(l);
18             return (l == r)? (l) : (0);
19         }
20         Mt = dep & 1; int md = (l + r) >> 1;
21         std::nth_element(p + l, p + md, p + 1 + r);
22         lc[md] = Build(l, md - 1, dep + 1);
23         rc[md] = Build(md + 1, r, dep + 1);
24         Up(md); return md;
25     }
26     inline int In_mi(int t) {
27         int re = 0;
28         re += std::max(qi.v[0] - r[t], 0);
29         re += std::max(l[t] - qi.v[0], 0);
30         re += std::max(qi.v[1] - u[t], 0);
31         re += std::max(d[t] - qi.v[1], 0);
32         return re;
33     }
34     inline int In_ma(int t) {
35         int re = 0;
36         re += std::max(std::abs(qi.v[0] - r[t]), std::abs(qi.v[0] - l[t]));
37         re += std::max(std::abs(qi.v[1] - u[t]), std::abs(qi.v[1] - d[t]));
38         return re;
39     }
40     void Query_mi(int t, int dep) {
41         if (!t) return; Mt = dep & 1;
42         if (qi != p[t]) ani = std::min(ani, Dis(qi, p[t]));
43         int dl = (lc[t])? (In_mi(lc[t])) : (INF);
44         int dr = (rc[t])? (In_mi(rc[t])) : (INF);
45         if (dl < dr) {
46             if (ani > dl) Query_mi(lc[t], dep + 1);
47             if (ani > dr) Query_mi(rc[t], dep + 1);
48         } else {
49             if (ani > dr) Query_mi(rc[t], dep + 1);
50             if (ani > dl) Query_mi(lc[t], dep + 1);
51         }
52     }
53     void Query_ma(int t, int dep) {
54         if (!t) return; Mt = dep & 1;
55         ana = std::max(ana, Dis(qi, p[t]));
56         int dl = (lc[t])? (In_ma(lc[t])) : (0);
57         int dr = (rc[t])? (In_ma(rc[t])) : (0);
58         if (dl > dr) {
59             if (ana < dl) Query_ma(lc[t], dep + 1);
60             if (ana < dr) Query_ma(rc[t], dep + 1);
61         } else {
62             if (ana < dr) Query_ma(rc[t], dep + 1);
63             if (ana < dl) Query_ma(lc[t], dep + 1);
64         }
65     }
66 }
View Code

相关文章:

  • 2022-12-23
  • 2021-11-30
  • 2021-06-29
  • 2021-07-06
  • 2021-07-22
  • 2021-06-29
  • 2022-02-24
猜你喜欢
  • 2021-10-12
  • 2021-11-09
  • 2022-12-23
相关资源
相似解决方案