【五十七】【算法分析与设计】IndexTree,IndexTree的作用,IndexTree流程,IndexTree代码

IndexTree作用

给你一个nums数组,实现查询区间和操作+单点更新nums数组操作。

可以使用IndexTree结构实现这两个操作。

IndexTree流程

1.

IndexTree的大小和nums数组大小相同。

2.

IndexTree下标必须从1开始,为了方便也将nums数组的下标一一对应。

3.

IndexTree[1]存储nums[1]。

IndexTree[2]存储nums[1]+nums[2]。

IndexTree[3]存储nums[3]。

IndexTree[4]存储nums[1]+nums[2]+nums[3]+nums[4]。

IndexTree[5]存储nums[5]。

IndexTree[6]存储nums[5]+nums[6]。

IndexTree[7]存储nums[7]。

IndexTree[8]存储nums[1]+nums[2]+nums[3]+nums[4]+nums[5]+nums[6]+nums[7]+nums[8]。

4.

一开始IndexTree[1]存储nums[1],线长度为1。

然后IndexTree[2]应该存储nums[2],如果存储nums[2]线长度为1,前面的线长度也是1,和我的相同,于是合并,线长度为2,表示存储nums[1]+nums[2]。

IndexTree[3]应该存储nums[3],线长度为1,前面线长度是2,不相同,不能合并。因此IndexTree[3]存储nums[3]。

IndexTree[4]应该存储nums[4],线长度为1,前面线长度也为1,相同合并,此时线长度为2,前面线长度为2,合并,此时线长度为4,表示nums[1]+nums[2]+nums[3]+nums[4],因此IndexTree[4]=nums[1]+nums[2]+nums[3]+nums[4]。

IndexTree[5]应该存储nums[5],线长度为1,前面线长度为4,不相同,因此IndexTree[5]=nums[5]。

IndexTree[6]应该存储nums[6],线长度为1,前面线长度为1,相同合并,此时线长度为2,前面线长度为4,不相同不能合并,因此IdnexTree[6]=nums[5]+nums[6]。

IndexTree[7]应该存储nums[7],线长度为1,前面线长度为2,不相同不能合并,因此IndexTree[7]=nums[7]。

IndexTree[8]应该存储nums[8],线长度为1,前面线长度为1,合并,此时线长度为2,前面线长度为2,合并此时线长度为4,前面线长度为4,合并此时线长度为8,表示nums[1]~nums[8],因此IndexTree[8]=nums[1]+nums[2]+nums[3]+nums[4]+nums[5]+nums[6]+nums[7]+nums[8]。

5.

如果我要查询nums数组 1~index区间的前缀和。

在IndexTree中,ret+=tree[index].这是第一个位置.

下一个位置是index-=lowbit(index).

ret+=tree[index].

下一个位置是index-=lowbit(index).

直到index越界为止.

6.

index-=lowbit(index)是什么意思?

首先lowbit(index) <==> index&(-index).

意思是在二进制中,保留最低位的1所代表的值.

index-=lowbit(index)意思是抹去最低位的1.

7.

如果我要单点更新nums数组index位置.加上c,IndexTree应该怎么变化?

首先IndexTree[index]+=c.

下一个位置index+=lowbit(index).

IndexTree[index]+=c.

下一个位置index+=lowbit(index).

直到index越界为止.

index+=lowbit(index)意思是加上最低位的1.

8.

如果要查询left~right区间和.

只需要前缀和right减去前缀和left-1.

9.

需要注意的是下标的映射关系.如果nums下标从0开始,IndexTree里面的下标对应的是1~n的下标.

可以想象IndexTree里面有个arr数组,和nums一样,唯一的区别是下标从1开始,IndexTree对应的是arr数组的下标.

IndexTree代码

 
class IndexTree {
public:int size;  // 树的大小vector<int> tree;  // 树的内部数据结构,用来存储部分和// 构造函数,初始化树的大小IndexTree(int _size) {size = _size + 1;  // 实际大小比输入大小大1,通常是为了方便处理从1开始的下标tree.resize(size);  // 调整内部数组的大小以匹配树的大小}// 计算低位的函数,用于确定区间的边界int lowbit(int i) {return i & -i;  // 返回i的最低位的1所对应的值}// 计算从树的起始位置到给定索引的所有元素的总和int sum(int index) {  // 对内的区间下标int ret = 0;  // 用于存储和的变量while (index > 0) {  // 从给定索引开始向树的根部移动ret += tree[index];  // 累加路径上的值index -= lowbit(index);  // 移动到下一个区间}return ret;  // 返回计算出的和}// 更新树的一个节点,增加一个值void add(int index, int d) {  // 对内的区间下标while (index <= size) {  // 从给定索引开始,向上更新所有相关的节点tree[index] += d;  // 更新当前节点index += lowbit(index);  // 移动到下一个需要更新的节点}}// 计算给定区间[l, r]的和int range(int l, int r) {  // 对外封装的函数,l和r是外界的区间下标return sum(r + 1) - sum(l);  // 通过差分计算区间和}
};int main() {vector<int> nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  // 初始数组IndexTree it(nums.size());  // 创建一个树状数组的实例for (int i = 0; i < nums.size(); i++) {it.add(i + 1, nums[i]);  // 初始化树状数组,将nums中的元素逐个添加进去}// 打印从每个元素开始到数组结束的所有区间和for (int left = 0; left < nums.size(); left++) {for (int right = left; right < nums.size(); right++) {cout << it.range(left, right) << " ";  // 输出每个区间的和}cout << endl;  // 每个起始点后换行}return 0;
}

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

【学习笔记十九】EWM Yard Management概述及后台配置

一、EWM Yard堆场管理业务概述 1.Yard Management基本概念 YARD管理针对的是库房以外的区域&#xff0c;可以理解为入大门开始到库门之前的这部分的区域 堆场结构 像在仓库中一样&#xff0c;将相应仓位映射为堆场仓位&#xff0c;可将其分组到堆场分区。场地中可能具有以下结…

C++相关概念和易错语法(5)(析构函数、拷贝构造、运算符重载、赋值重载)

上篇文章分享了一些构造函数和析构函数的易错点&#xff0c;这篇文章则将继续分享一些构造函数、拷贝构造函数的易错点。 1.变量声明处赋缺省值 我们已经知道了自动构造函数的初始化规则了。我们可以认为这个初始化规则比较保守&#xff0c;能不修改成员变量的值就不修改&…

大厂高频面试题:ReentrantLock 与 synchronized异同点对比

写在开头 在过去的博文中我们学习了ReentrantLock 与 synchronized这两种Java并发使用频率最高的同步锁&#xff0c;在很多大厂面试题中有个经典考题&#xff1a; ReentrantLock 与 synchronized异同点对比&#xff01; 今天我们针对这一考题来做一个尽可能全面的总结哈。 Re…

UML/SysML建模工具更新情况-截至2024年4月(1)5款-Trufun建模平台 v2024

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 工具最新版本&#xff1a;itemis CREATE 5.2.2 更新时间 2024年3月22日 工具简介 原名YAKINDU Statechart Tools。状态机建模工具&#xff0c;支持各种语言的代码生成&#xff0c;提…

B2024 输出浮点数 洛谷题单

首选需要进行了解的就是%a.bf所代表的含义就行了&#xff0c;直接莽了&#xff0c;没啥解释的笑脸&#x1f644; 在 Python 中&#xff0c;%a.bf 中的参数 a 和 b 是用来格式化浮点数的输出的&#xff0c;具体含义如下&#xff1a; a 表示总输出宽度&#xff0c;包括小数点、…

链表基础4——带头双向循环链表(c语言实现)

什么是带头双向循环链表 我们直接看图片 定义结点类型 typedef int LTDataType;//存储的数据类型typedef struct ListNode {LTDataType data;//数据域struct ListNode* prev;//前驱指针struct ListNode* next;//后继指针 }ListNode;链表的初始化 //创建一个新结点 ListNod…

什么是反向 ETL?为什么它很有价值?

提取、转换、加载 &#xff08;ETL&#xff09; 过程已经成熟并被广泛采用。 它只涉及从各种源系统中获取数据&#xff0c;将其转换为标准化数据模型&#xff0c;然后将其加载到数据仓库中。从那里&#xff0c;您的团队使用其商业智能 &#xff08;BI&#xff09; 和分析工具中…

FPGA - ZYNQ Cache一致性问题

什么是Cache&#xff1f; Cache是一种用来提高计算机运行速度的一种技术。它是一种小而快的存储设备&#xff0c;位于CPU与内存之间&#xff0c;用于平衡高速设备与低速设备之间的速度差异。Cache可以存储常用的数据或指令&#xff0c;以便CPU更快地获取&#xff0c;从而减少对…

基于单片机的智能病床呼叫系统设计与仿真

摘 要 本文设计的病床呼叫系统采用单片机作为控制器。该系统具有远程控制、病人的身体情况检测、报警呼叫、显示和执行器运动的功能。远程控制由红外线传感器和矩阵键盘组成&#xff0c;检测电路由温湿度传感器DH22、心率传感器Pulse Sensor、压力传感器MPX4115组成&#x…

操作系统——进程

进程定义 是计算机中已经运行的程序是系统进行资源分配和调度的一个独立单位。 进程的特性 独立性&#xff1a;进程在内存中可以独立寻址&#xff0c;每个进程都有一个独立的堆栈空间。动态性&#xff1a;进程在执行过程中可以申请资源、使用资源、释放资源。并发性&#xf…

OceanBase开发者大会2023届视频及PPT汇总

数据库技术趋势 我眼中的数据库技术 阳振坤OceanBase 首席科学家 观看视频 下载 PDF 未来&#xff0c;中国需要什么样的数据库&#xff1f; 周傲英华东师范大学副校长&#xff0c;CCF 会士 观看视频 下载 PDF 云原生技术趋势解读 Keith ChanCNCF 云原生计算基金会中国区总监 …

批量规范化(batchnormalization)

ˆB 是小批量B的样本均值&#xff0c;σˆ B 是小批量B的样本标准差。应用标准化后&#xff0c;生成的小批量的平均 值为0和单位方差为1。由于单位方差&#xff08;与其他一些魔法数&#xff09;是一个主观的选择&#xff0c;因此我们通常包含 拉伸参数&#xff08;scale&#…