当前位置: 首页 > news >正文

KD Tree

KD Tree

在第 \(k\) 维上的单次查询复杂度最坏为 \(\mathcal O(n^{1-k^{-1}})\)

struct KDT {constexpr static int N = 1e5 + 10, K = 2;double alpha = 0.725;struct node {int info[K];int mn[K], mx[K];} tr[N];int ls[N], rs[N], siz[N], id[N], d[N];int idx, rt, cur;int ans;KDT() {rt = 0;cur = 0;memset(ls, 0, sizeof ls);memset(rs, 0, sizeof rs);memset(d, 0, sizeof d);}void apply(int p, int son) {if (son) {for (int i = 0; i < K; i++) {tr[p].mn[i] = min(tr[p].mn[i], tr[son].mn[i]);tr[p].mx[i] = max(tr[p].mx[i], tr[son].mx[i]);}siz[p] += siz[son];}}void maintain(int p) {for (int i = 0; i < K; i++) {tr[p].mn[i] = tr[p].info[i];tr[p].mx[i] = tr[p].info[i];}siz[p] = 1;apply(p, ls[p]);apply(p, rs[p]);}int build(int l, int r) {if (l > r) return 0;vector<double> avg(K);for (int i = 0; i < K; i++) {for (int j = l; j <= r; j++) {avg[i] += tr[id[j]].info[i];}avg[i] /= (r - l + 1);}vector<double> var(K);for (int i = 0; i < K; i++) {for (int j = l; j <= r; j++) {var[i] += (tr[id[j]].info[i] - avg[i]) * (tr[id[j]].info[i] - avg[i]);}}int mid = (l + r) / 2;int x = max_element(var.begin(), var.end()) - var.begin();nth_element(id + l, id + mid, id + r + 1, [&](int a, int b) {return tr[a].info[x] < tr[b].info[x];});d[id[mid]] = x;ls[id[mid]] = build(l, mid - 1);rs[id[mid]] = build(mid + 1, r);maintain(id[mid]);return id[mid];}void print(int p) {if (!p) return;print(ls[p]);id[++idx] = p;print(rs[p]);}void rebuild(int &p) {idx = 0;print(p);p = build(1, idx);}bool bad(int p) {return alpha * siz[p] <= max(siz[ls[p]], siz[rs[p]]);}void insert(int &p, int cur) {if (!p) {p = cur;maintain(p);return;}if (tr[p].info[d[p]] > tr[cur].info[d[p]]) insert(ls[p], cur);else insert(rs[p], cur);maintain(p);if (bad(p)) rebuild(p);}void insert(vector<int> &a) {cur++;for (int i = 0; i < K; i++) {tr[cur].info[i] = a[i];}insert(rt, cur);}bool out(int p, vector<int> &a) {for (int i = 0; i < K; i++) {if (a[i] < tr[p].mn[i]) {return true;}}return false;}bool in(int p, vector<int> &a) {for (int i = 0; i < K; i++) {if (a[i] < tr[p].info[i]) {return false;}}return true;}bool all(int p, vector<int> &a) {for (int i = 0; i < K; i++) {if (a[i] < tr[p].mx[i]) {return false;}}return true;}void query(int p, vector<int> &a) {if (!p) return;if (out(p, a)) return;if (all(p, a)) {ans += siz[p];return;}if (in(p, a)) ans++;query(ls[p], a);query(rs[p], a);}int query(vector<int> &a) {ans = 0;query(rt, a);return ans;}
};
http://www.hskmm.com/?act=detail&tid=38045

相关文章:

  • ST 表
  • 小波矩阵树:高效静态区间第 K 大查询
  • Seata用法
  • 分数运算类
  • 撸一个功能强大的基于语义的图像检索系统
  • 提交一张 PPT,参与 RTE2025 全球语音智能体云展示
  • 解释 EIP-4337
  • 数论常见结论及例题
  • 求解连续数字的正约数集合——倍数法
  • git回滚代码
  • 组合数
  • q
  • 裴蜀定理
  • 逆元
  • 扩展欧几里得 exgcd
  • 离散对数 bsgs 与 exbsgs
  • 常见数列
  • 20232314 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 【LTDC】LTDC 简介
  • 分类器案例 - -一叶知秋
  • Markdown数学公式 - -一叶知秋
  • 最大流
  • 最小割树 Gomory-Hu Tree
  • 最小割
  • 差分约束
  • 图论常见结论及例题
  • 最长路(topsort+DP算法)
  • 二分图最大匹配
  • 最短路径树(SPT问题)
  • 欧拉路径/欧拉回路 Hierholzers