zkw线段树

介绍

非递归线段树实现方法,码量较短。

zkw 线段树的构造原理:

普通线段树采用堆存储,zkw线段树 本质上是满二叉树(若没有该区间则为空点)

但根据实际情况,原区间不一定构成满二叉树,据查询方式限制,空间开到最接近的 \(2^n\)(据性质树值域 = 底层节点数),即不存在的点有虚点填充。

既然不存在区间也需用空点填充,zkw线段树 对比 普通线段树 空间较大?

相比于普通线段树的结构混乱,一般开到 4 倍空间,而 zkw线段树 则只大约开到 3 倍空间

普通线段树本质上是从上往下搜索,从根节点向下操作。

zkw 线段树不同于普通线段树,本质上是从下往上搜索,从叶子节点向上操作。

zkw 线段树的基本操作

建树操作:

while (m <= n) {m <<= 1;
}
for (int i = m + 1; i <= m + n; ++ i) {tr[i] = read ();
}
m -= 1;
while (m --) {solve ();
}

维护区间和:\(\tt tr[] \rightarrow sum[]\)

solve () : sum[i] = sum[i << 1] + sum[i << 1 | 1];

维护区间最小值:\(\tt tr[] \rightarrow minn[]\)

solve () : minn[i] = min (minn[i << 1], minn[i << 1 | 1]); // 不支持修改
solve () : minn[i] = min (minn[i << 1], minn[i << 1 | 1]);
minn[i << 1] -= minn[i];
minn[i << 1 | 1] -= minn[i];

维护区间最大值:\(\tt tr[] \rightarrow maxx[]\)

solve () : maxx[i] = max (maxx[i << 1], maxx[i << 1 | 1]); // 不支持修改
solve () : maxx[i] = max (maxx[i << 1], maxx[i << 1 | 1]);
maxx[i << 1] -= maxx[i];
maxx[i << 1 | 1] -= maxx[i];

单点查询:

沿根节点向叶子节点累计加和

ll total = 0;
for (int i = id + m; i; i >>= 1) {total += minn[i]; 
}

单点修改:

修改当前节点并更新父亲节点

tr[id = id + m] += v;
while (m) {solve ();m >>= 1;
}

维护区间和:\(\tt tr[] \rightarrow sum[]\)

solve () : sum[i] = sum[i << 1] + sum[i << 1 | 1];

维护区间最小值:\(\tt tr[] \rightarrow minn[]\)

solve () : minn[i] = min (minn[i << 1], minn[i << 1 | 1]); // 不支持修改
solve () : minn[i] = min (minn[i << 1], minn[i << 1 | 1]);
minn[i << 1] -= minn[i];
minn[i << 1 | 1] -= minn[i];

维护区间最大值:\(\tt tr[] \rightarrow maxx[]\)

solve () : maxx[i] = max (maxx[i << 1], maxx[i << 1 | 1]); // 不支持修改
solve () : maxx[i] = max (maxx[i << 1], maxx[i << 1 | 1]);
maxx[i << 1] -= maxx[i];
maxx[i << 1 | 1] -= maxx[i];

区间查询

图片来源于网络(https://csacademy.com/app/graph_editor/)

假定先需查询区间 \([1,4]\) 那么操作如下:

  1. 闭区间改开区间:\([1,4] \rightarrow (0,5)\) 扩增至 \((M + 0, M + 5) = (8,13)\)
  2. 判断:左端点 \(1000\) 为 左儿子,其兄弟节点必在区间内,累加 \(total += D[1001_B]\);判断:右端点 \(1101\) 为右儿子,其兄弟节点必在区间内,累加 \(total += D[1101_B]\)
  3. 缩小区间:\(\tt l >>= 1\) \(\rightarrow\) \(\tt 1000_B >> 1 = 0100_B,\) \(\tt r >>= 1\) \(\rightarrow\) \(\tt 1101_B >> 1 = 0110_B\)
  4. 判断:左端点 \(0100\) 为 左儿子,其兄弟节点必在区间内,累加 \(total += D[0101_B]\);判断:右端点 \(1101\) 为左儿子,不操作
  5. 缩小区间:\(\tt l >>= 1\) \(\rightarrow\) \(\tt 0100_B >> 1 = 0010_B,\) \(\tt r >>= 1\) \(\rightarrow\) \(\tt 0110_B >> 1 = 0011_B\)
  6. 此时 节点 \(\tt l\) 和 节点 \(\tt r\) 为兄弟节点,停止操作。

伪代码:

for (int l = 开区间左端点, r = 开区间右端点; l, r 不是兄弟节点; 缩小区间) {if (l 为左儿子) {total += c[l 的兄弟节点];}if (r 为右儿子) {total += c[r 的兄弟节点];}
}

维护区间和:

for (int l = l + m - 1, r = r + m - 1, l ^ r ^ 1; l >>= 1, r >>= 1) {if (~ l & 1) {total += c[l ^ 1];}if (r & 1) {total += c[r ^ 1];}
}

维护区间最小值:

ll L = 0, R = 0;
for (int l = l + m - 1, r = r + m - 1; l ^ r ^ 1; l >>= 1, r >>= 1) {L += minn[l], R += minn[r];if (~ l & 1) {L = min (L, minn[l ^ 1]);}if (r & 1) {R = min (R, minn[r ^ 1]);}
}
ll res = min (L, R);
while (l) {res += minn[l >>= 1];
}

维护区间最大值:

ll L = 0, R = 0;
for (int l = l + m - 1, r = r + m - 1; l ^ r ^ 1; l >>= 1, r >>= 1) {L += maxx[l], R += maxx[r];if (~ l & 1) {L = max (L, maxx[l ^ 1]);}if (r & 1) {R = max (R, maxx[r ^ 1]);}
}
ll res = max (L, r);
while (l) {res += maxx[l >> 1];
}

区间修改

咕了。

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

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

相关文章

张昆玮线段树

zkw 线段树 - 非递归线段树实现方法介绍 非递归线段树实现方法,码量较短。 zkw 线段树的构造原理: 普通线段树采用堆存储,zkw线段树 本质上是满二叉树(若没有该区间则为空点) 但根据实际情况,原区间不一定构成满二叉树,据查询方式限制,空间开到最接近的 \(2^n\)(据性质…

全红婵夺冠!数业智能心大陆告诉你原生家庭在背后发挥了怎样的力量

2024年巴黎,全红婵在十米跳台上的完美一跃, 再次定义了跳水艺术,水花消失术成为她的代名词!全红婵的辉煌成就,不仅点亮了自己,也照亮了家庭的未来。 而他的家人也非常珍视全红婵的成功。 其父亲坚定的表示:”我们不能消费女儿“。 “不能因为她拿了冠军,我连活都不干了。…

无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案[含ollama部署]

无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案-含ollama部署无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案 1.Dify 简介 1.1 功能情况 Dify,一款引领未来的开源大语言…

基于 JavaFx 搭建的实用小工具集合

xJavaFxTool —— 一个基于 JavaFx 搭建的实用小工具集合,包括文件复制、Cron表达式生成器、编码转换、加密解密等几十种开发中常用的工具。大家好,我是 Java陈序员。 作为一名后端程序员,常常需要在电脑上安装各种工具软件来支持日常开发。 那么,是否有一款工具集合,包含…

ubuntu开机等待网络连接问题

修改/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service文件sudo vim /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service添加内容:TimeoutStartSec=2sec 修改sudo vim /etc/netplan/01-network-manage…

(七)Redis 持久化 AOF、RDB

Redis 持久化 AOF、RDBRedis 一旦服务器宕机,内存中的数据将全部丢失,从后端数据库恢复这些数据,对数据库压力很大,且性能肯定比不上从 Redis 中读取,会拖慢应用程序。所以,对 Redis 来说,实现数据的 持久化 ,避免从后端数据库中进行恢复,是至关重要的。 1、AOF 日志 …

uniapp 渲染卡顿的几个问题

1.渲染时禁止使用 uni.getStorageSync。会卡顿2.做大量的浮点运算。数据类型转换等。能先算好的就算好。

观存储历史,论数据未来

在探索未来的数据存储技术时,我们不禁感慨于人类智慧的无限可能。从古代的竹简、木简,到蔡伦的造纸术,再到现代的机械硬盘、固态硬盘,直至云存储和前沿的DNA存储与量子存储,技术的演进总是令人惊叹。历史告诉我们,在时间面前,所有不可逾越的技术壁垒都是纸老虎。对于程序…

洛谷题单指南-前缀和差分与离散化-P5937 [CEOI1999] Parity Game

原题链接:https://www.luogu.com.cn/problem/P5937 题意解读:已知长度为n的01序列,给出m个判断,每个判断认为l~r之间1的个数是偶数或者奇数,计算前多少个判断是正确的。 解题思路: 先用前缀和思想来思考本题:假设s[i]是序列前i个数的和 对于每一个判断,有两种可能 第一…

深入理解 PHP 高性能框架 Workerman 守护进程原理

守护进程顾名思义就是能够在后台一直运行的进程,不会霸占用户的会话终端,脱离了终端的控制。相信朋友们对这东西都不陌生了吧?如果连这个概念都还不能理解的话,建议回炉重造多看看 Linux 进程管理相关的基础知识。大家好,我是码农先森。 守护进程顾名思义就是能够在后台一…

IT基础书籍汇集_sum

希望STUDENT过软考,所以有些基础书籍还是需要看看 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------虽然书籍,标注“著”的书籍…

antd表单的<a-form-item>使用自定义label插槽

item的label类型可以使字符串或者自定义label插槽。 1.直接使用字符串类型是最常见的<a-form-model-item prop="job" label="岗位"><a-input v-model="job" placeholder="请输入岗位" /> </a-form-model-item> 2.自…