K-D 树 笔记

news/2025/3/26 17:38:34/文章来源:https://www.cnblogs.com/Garbage-fish/p/18790083

用于解决 \(k\) 维区间问题的数据结构。

P4148 简单题

这是一种 2-D 树,因为只有两维。

K-D 树用的是类似平衡树的思路,也就是根节点本身也代表一个节点信息,故选择一个维度,用 nth_element 函数找到这个维度居中的点,把它作为根节点即可。

对于一个正方形,横着切一刀竖着切一刀时间复杂度显然优,但是要是对于一个平放的木棍,横着切完全没必要,所以每次按照方差较大的维度进行分治。

插入点之后,不平衡了怎么办?直接用替罪羊树思路暴力重建。具体地,设定一个 \(\alpha=0.75\),若某个点的儿子的子树大小,已经超过了这个点的子树大小的 \(\alpha\) 倍,就把这整个子树的点记录下来,直接重建。

查询的时候,如果是像例题中这种求和,就只能暴力求了,但是如果是求距离最小值 / 最大值,显然可以用各种爆搜用的贪心剪枝,时间复杂度就是 \(O(?)\) 了。

超长代码预警。

namespace KD {
#define mid (l + r >> 1)const double alpha = 0.7;struct TREE {int ls, rs, x, y, v;int x1, y1, x2, y2, s, sz;int d;} t[N];int p[N], np, root, idx;void push_up(int rt) {t[rt].s = t[t[rt].ls].s + t[t[rt].rs].s + t[rt].v;t[rt].sz = t[t[rt].ls].sz + t[t[rt].rs].sz + 1;t[rt].x1 = t[rt].x2 = t[rt].x;t[rt].y1 = t[rt].y2 = t[rt].y;if (t[rt].ls) {t[rt].x1 = min(t[rt].x1, t[t[rt].ls].x1);t[rt].y1 = min(t[rt].y1, t[t[rt].ls].y1);t[rt].x2 = max(t[rt].x2, t[t[rt].ls].x2);t[rt].y2 = max(t[rt].y2, t[t[rt].ls].y2);}if (t[rt].rs) {t[rt].x1 = min(t[rt].x1, t[t[rt].rs].x1);t[rt].y1 = min(t[rt].y1, t[t[rt].rs].y1);t[rt].x2 = max(t[rt].x2, t[t[rt].rs].x2);t[rt].y2 = max(t[rt].y2, t[t[rt].rs].y2);}}void getp(int rt) {if (!rt)return;p[++np] = rt;getp(t[rt].ls), getp(t[rt].rs);}bool cmpx(int x, int y) {return t[x].x < t[y].x;}bool cmpy(int x, int y) {return t[x].y < t[y].y;}void build(int &rt, int l, int r) {if (l > r) {rt = 0;return;}double avx = 0, avy = 0, sx = 0, sy = 0;for (int i = l; i <= r; i++)avx += t[p[i]].x, avy += t[p[i]].y;avx = 1.0 * avx / (r - l + 1), avy = 1.0 * avy / (r - l + 1);for (int i = l; i <= r; i++) {sx += (t[p[i]].x - avx) * (t[p[i]].x - avx);sy += (t[p[i]].y - avy) * (t[p[i]].y - avy);}if (sx > sy) {nth_element(p + l, p + mid, p + r + 1, cmpx);rt = p[mid];t[rt].d = 1;} else {nth_element(p + l, p + mid, p + r + 1, cmpy);rt = p[mid];t[rt].d = 2;}build(t[rt].ls, l, mid - 1);build(t[rt].rs, mid + 1, r);push_up(rt);}void rebuild(int &rt) {if (max(t[t[rt].ls].sz, t[t[rt].rs].sz) <= t[rt].sz * alpha)return;np = 0;getp(rt);build(rt, 1, np);}void update(int &rt, int v) {if (!rt) {rt = v;push_up(rt);return;}if (t[rt].d == 1)t[v].x <= t[rt].x ? update(t[rt].ls, v) : update(t[rt].rs, v);elset[v].y <= t[rt].y ? update(t[rt].ls, v) : update(t[rt].rs, v);push_up(rt);rebuild(rt);}int query(int rt, int x1, int y1, int x2, int y2) {if (!rt or t[rt].x1 > x2 or t[rt].y1 > y2 or t[rt].x2 < x1 or t[rt].y2 < y1)return 0;if (x1 <= t[rt].x1 and t[rt].x2 <= x2 and y1 <= t[rt].y1 and t[rt].y2 <= y2)return t[rt].s;int ret = 0;if (x1 <= t[rt].x and t[rt].x <= x2 and y1 <= t[rt].y and t[rt].y <= y2)ret = t[rt].v;return ret + query(t[rt].ls, x1, y1, x2, y2) + query(t[rt].rs, x1, y1, x2, y2);}
}
using namespace KD;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904950.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】力扣 102. 二叉树的层序遍历★

102. 二叉树的层序遍历 中等 提示 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1:输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]示例 2: 输入:root = [1] 输出:[[1]]示例 3: 输入:root = [] 输…

【Azure Container App】在消耗性的Container App Environmnet中无法查看当时正在使用多少CPU多少实例数的替代方案

问题描述 在Azure上使用Container App服务,创建服务环境的时候,选择类型为消耗型(Consumption)。但是,却无法查看当前所有应用中,具体使用了多少个 core (CPU), 目前有多少个实例呢? 如上图,上面的信息是 “-” 问题解答 因为在Container App Environment中所使用的Workl…

Redis短信登录场景

1、Redis短信登录场景 1.1、整体流程1.1、发送短信验证码 @Service @Slf4j public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic Result sendCode(String phone, HttpSession session) {// 1、校验手机号是否…

威联通TS-466C

威联通TS-466C CPU: Intel奔腾 银牌N6005 四核/ 四线程处理器,可高达 3.3 GHz 内存: 8G 3200MHz (可扩容到16G) 最大硬盘容量: 96T(22TB HDD x 4 + 4TB M.2 x 2)官网硬件参数: https://www.qnap.com.cn/zh-cn/product/ts-466c/specs/hardware 开箱安装硬盘 M2固态安装机械硬盘…

SvelteKit 最新中文文档教程(9)—— 部署静态站点与单页应用

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

FeedbackStream:8 分钟创建 AI 面试智能体;Moshi 开源图像理解实时语音模型 MoshiVis 丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看点的 活动 」,但内容仅代表编辑…

20234120 2024-2025-2 《Python程序设计》实验一报告

20234120 2024-2025-2 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2341 姓名: 李卓颖 学号:20234120 实验教师:王志强老师 实验日期:2025年3月22日 必修/选修:专业选修课 一、实验内容 (一)准备工作:1.安装Python和PyCharm:访问Python和PyCharm官…

day:28 postman——断言

一.postman 断言 1.断言再test中 状态码是否等于200: tests["Status code is 200"] = responseCode.code === 200; 断言响应时间小于200ms: tests["Response time is less than 200ms"] = responseTime < 200; 断言响应体包含内容: tests["Bod…

XDA论坛打不开的解决办法

开了梯子反而进不去,关掉全局代理 v2 可以添加两行 https://xdaforums.com/; https://www.xda-developers.com/;

国内首个HR智能体平台:开启人力资源管理智能化征程

在当今数字化飞速发展的浪潮中,人工智能已不再是一个遥远的概念,而是实实在在地渗透到了各个领域,深刻改变着我们的工作与生活方式。人力资源管理,这一关乎企业核心竞争力的关键环节,也正经历着AI技术带来的前所未有的变革。HR智能体作为这一变革中的重要成果,正逐渐成为…

爆火开源库!20K星标,一键让网页设计秒变手绘风

今天必须给大伙说说一个超有意思的开源库,在GitHub上已经斩获20K星标啦,它能轻松给网页设计加上手绘风格的“滤镜”,让页面瞬间告别千篇一律,充满艺术感!一、Rough.js是什么?这个名为Rough.js轻量级的图形库,大小才8KB,能赋予网页元素自然又独特的手绘质感。通过一套特…