(C++) 树状数组

目录

一、介绍

二、一维树状数组

        2.1 区间长度

        2.2 前驱和后继

        2.3 查询前缀和

        2.4 点更新

三、一维数组的实现

        3.1 区间长度函数

        3.2 前缀和

        3.3 插入/更新

        3.4 封装成类


一、介绍

        树状数组(Binary Indexed Tree,BIT),又称为 Fenwick 树,是一种高效的数据结构,主要用于动态维护数组的前缀和(或区间和),以及支持单点更新的操作。其核心思想是利用二进制的特性,通过巧妙地设计数据结构,对每一部分设置了一个“管理员”,管理员存储量其管理对象的所和,从而实现快速的区间查询和单点更新操作。因此当需要对前n和数据进行求和的时候就不需要遍历n次,只需要查询对应管理员中的数值即可。

        本篇仅仅介绍一维的树状数组,多维的原理和此是一样的。

二、一维树状数组

        这里需要了解几个关于树状数组的几个定义。

        首先我们定义一个管理数组c[i],也就是上面提到的“管理员”。管理员的个数和一维数组的元素个数相同。

        再定义所有存储的一维数组为a[i]

        2.1 区间长度

        这里的区间长度指的是每一个管理员所管理的具体对象的多少。对于c[i],若i的二进制末尾有k个连续的0,则c[i]存储的区间长度为2^{k},即从a[i]向前数2^{k}个元素的累加和。例如,6的二级制为110,末尾有1个0,区间长度为2,就存储了a[5],a[6],即c[6] = a[5] + a[6]

        得到二进制末尾连续0的个数的方法是,将该二进制数取反后加一,再与原值做与运算。例如:20的二进制为10100,是原始二进制数,取反后为01011,加1后为01100,此时最低位的1和原数最低位的1的位置是一样的,01100和10100做与运算就得到了00100

i = 20 = 10100

\widetilde{i} = 01011        取反

01011+1=01100

01100 & 10100=00100 = 4

得到的区间长度为4。这里定义lowbit(i)函数得到的是区间的长度。

        2.2 前驱和后继

        直接的前驱为c[i-lowbit(i)]

        直接的后继为c[i+lowbit(i)]

        前驱:c[i]的直接前驱,直接前驱的直接前驱...

        后继:c[i]的直接后继,直接后继的直接后继...

        2.3 查询前缀和

        前i个元素的前缀和sum[i]等于c[i]加上c[i]的前驱。例如sum(5)c[5]加上c[5]的前驱。而c[5]的前驱为c[4],且c[4]没有前驱,故sum(5) = c[5] + c[4]

        解释一下c[5]的前驱。i=5,其二进制为0101,末尾没有0,故区间长度为1(2的0次方),则其前驱为c[5-1]=c[4],同理可得c[4]没有前驱,故只有一个前驱。

        2.4 点更新

        若对a[i]进行了修改,加上了z,则只需要更新c[i]以及后继即可,让所有的都加上z。因为该更新只会改变其本身和后继的数值,对前驱是没有影响的。

        需要注意的是,树状数组的下标需要从1开始,否则lowbit(0)=0会出现死循环。

三、一维数组的实现

        3.1 区间长度函数

        在计算机中,使用二进制的补码进行表示刚好是 i 取反加1,因此-i = \widetilde{i} + 1

int lowbit(int i)
{return (-i) & i;	//计算区间区间的大小
}

        3.2 前缀和

int sum(int i)
{int s = 0;for (; i > 0; i -= lowbit(i)){s += c[i];}return s;
}

        3.3 插入/更新

        该函数可以用来更新数值,也可以用来创建树状数组。只要把c[i]初始化为0,z 遍历a[i]插入即可。

void add(int i, int z)
{for (; i <= 9; i += lowbit(i)){c[i] += z;}

        3.4 封装成类

class BITree
{
private:std::vector<int> c;			//存储树的节点和int size;					//数组的大小int lowbit(int i);			//计算区间的大小
public:BITree(int n);				//输入数据量void Update(int i, int z);	//修改数据int sum(int i);			//查询
};BITree::BITree(int n)
{size = n;c.resize(n + 1, 0);
}int BITree::lowbit(int i)
{return (-i) & i;
}void BITree::Update(int i, int z)
{for (; i <= 9; i += lowbit(i)){c[i] += z;}
}int BITree::sum(int i)
{int s = 0;for (; i > 0; i -= lowbit(i)){s += c[i];}return s;
}

测试:

int main()
{int a[9] = { 1,2,3,4,5,6,7,8,9 };for (int i = 0; i < 9; i++){add(i + 1, a[i]);}std::cout << sum(9) << std::endl;BITree tree(9);for (int i = 0; i < 9; i++){tree.Update(i + 1, a[i]);}std::cout << tree.sum(4) << std::endl;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于MLP算法实现交通流量预测(Pytorch版)

在海量的城市数据中&#xff0c;交通流量数据无疑是揭示城市运行脉络、洞察出行规律的关键要素之一。实时且精准的交通流量预测不仅能为交通规划者提供科学决策依据&#xff0c;助力提升道路使用效率、缓解交通拥堵&#xff0c;还能为公众出行提供参考&#xff0c;实现个性化导…

【软件测试】认识测试|测试岗位|软件测试和开发的区别|优秀的测试人员需要具备的素质

一、什么是测试 测试在⽣活中处处可⻅ 1.生活中的测试场景 案例⼀&#xff1a;对某款购物软件进⾏测试 *启动测试&#xff1a;点击软件图标&#xff0c;测试软件是否可以正常打开 搜索测试&#xff1a;点击输入框&#xff0c;输入关键词&#xff0c;点击搜索 商品测试&#…

Web3革命:区块链如何重塑互联网

引言 互联网的发展已经深刻地改变了我们的生活方式&#xff0c;而现在&#xff0c;Web3和区块链技术正在为我们提供一个全新的数字世界的视角。本文将带你深入了解Web3的核心概念、技术特性以及它如何正在重塑我们的互联网体验。 从Web1.0到Web3&#xff1a;数字革命的演进 W…

羊大师分析,夏季羊奶的适合人群有哪些?

羊大师分析&#xff0c;夏季羊奶的适合人群有哪些&#xff1f; 夏季羊奶的适合人群相当广泛&#xff0c;主要包括以下几类人群&#xff1a; 生长发育中的孩子&#xff1a;羊奶富含营养&#xff0c;特别是蛋白质和矿物质&#xff0c;对孩子的生长发育有积极的促进作用。 中老年…

谈谈mysql中的各个关键字

1.为什么学习mysql mysql是当今最主流且开放源码的关系型数据库&#xff0c;开发者为瑞典 MySQL AB 公司。目前 MySQL 被广泛地应用在 Internet 上的中小型网站中。由于其体积小、速度快、总体拥有成本低&#xff0c;尤其是开放源码这一特点&#xff0c;许多中小型网站为了降低…

电商巨头亚马逊公布新算法!或将颠覆跨境选品风向…

亚马逊每一次算法的变动&#xff0c;都会牵扯到无数卖家的利益。电商巨头亚马逊发布了一则报告&#xff0c;正式公布了一个名为“COSMO”的新算法。该算法全称为“亚马逊大型电商常识知识生成与服务系统”&#xff0c;顾名思义&#xff0c;就是利用大量语言模型训练机器&#x…

学习c语音的自我感受

因为是自学&#xff0c;所以走过不少弯路。去年&#xff0c;受知乎“python性能弱”风潮的影响&#xff0c;学过go,rust。 在学习这些新语言的时候&#xff0c;由衷感受到&#xff0c;或是本身侧重方向的原因&#xff08;如go侧重服务器&#xff09;&#xff0c;或是语言太新不…

【面试经典 150 | 数组】最长公共前缀

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;横向扫描方法二&#xff1a;纵向扫描方法三&#xff1a;分治 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#x…

Nginx 四层和七层代理

四层&#xff1a;通过报文中的目标地址和端口&#xff0c;加上负载均衡设备设置的服务器选择方式&#xff0c;决定最终选择的内部服务器&#xff0c;使用tcp、udp协议。 七层&#xff1a;"内容交换"&#xff0c;通过报文中真正有意义的应用层内容&#xff0c;加上负…

多商家AI智能名片商城系统(开源版)——构建高效数字化商业新生态

一、项目概述 1、项目背景 1&#xff09;起源 随着数字化时代的快速发展&#xff0c;传统名片和商城系统已经难以满足企业日益增长的需求。商家需要更高效、更智能的方式来展示自己的产品和服务&#xff0c;与消费者进行互动和交易。同时&#xff0c;开源技术的普及也为开发…

ubuntu16安装docker及docker-compose

ubuntu16安装docker及docker-compose 一、环境前期准备 检查系统版本 系统版本最好在16及以上&#xff0c;可以确保系统的兼容性 lsb_release -a查看内核版本及系统架构 建议用 x86_64的系统架构&#xff0c;安装是比较顺利的 uname -a32的系统不支持docker&#xff0c;安…

【python进阶篇】装饰器(6)

在Python中&#xff0c;修饰器&#xff08;也称为装饰器&#xff09;是一个高级Python功能&#xff0c;它允许你修改或增强函数、方法或类的行为&#xff0c;而无需修改其源代码。修饰器本质上是一个接受函数作为参数的可调用对象&#xff08;通常是另一个函数&#xff09;&…

Spring-IOC之组件扫描

版本 Spring Framework 6.0.9​ 1. 前言 通过自动扫描&#xff0c;Spring 会自动从扫描指定的包及其子包下的所有类&#xff0c;并根据类上的特定注解将该类装配到容器中&#xff0c;而无需在 XML 配置文件或 Java 配置类中逐一声明每一个 Bean。 支持的注解 Spring 支持一系…

编程基础“四大件”

基础四大件包括&#xff1a;数据结构和算法,计算机网络,操作系统,设计模式 这跟学什么编程语言,后续从事什么编程方向均无关&#xff0c;只要做编程开发&#xff0c;这四个计算机基础就无法避开。可以这么说&#xff0c;这基础四大件真的比编程语言重要&#xff01;&#xff0…

(一)、SQL进阶——神奇的SQL

一、CASE表达式 1、CASE表达式概述 case表达式有简单case表达式和搜索case表达式两种写法 -- 简单case表达式 case sex when 1 then 男 when 0 then 女 else 其他 end -- 搜索case表达式 case when sex1 then 男 when sex1 then 男 else 其他 end 这两种写法执行的结…

操作系统原理与实验——实验九分页式存储

实验指南 运行环境&#xff1a; Dev c 算法思想&#xff1a; 本实验模拟分页存储管理&#xff0c;对于需要分配资源的作业&#xff0c;预先申请空间&#xff0c;内存空间满足要求&#xff0c;进行内存分配并插入作业链表&#xff0c;打印该作业页表信息与系统内存信息。对于需要…

【QT学习】9.绘图,三种贴图,贴图的转换

一。绘图的解释 Qt 中提供了强大的 2D 绘图系统&#xff0c;可以使用相同的 API 在屏幕和绘图设备上进行绘制&#xff0c;它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作&#xff0c;其提供的 API 在 GUI 或 QImage、QOpenGLPaintDev…

路由引入实验

配置思路&#xff1a; 1.IP配置&#xff1a; [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip ad 100.1.1.1 24 [R1-GigabitEthernet0/0/0]int l0 [R1-LoopBack0]ip ad 192.168.0.1 32 [R1-LoopBack0]int l1 [R1-LoopBack1]ip ad 192.168.1.1 32 [R1-LoopBack1]q dis ip int bri…

海康Visionmaster-常见问题排查方法-启动阶段

VM试用版启动时&#xff0c;弹窗报错&#xff1a;加密狗未安装或检测异常&#xff1b;  问题原因&#xff1a;安装VM 的时候未选择软加密&#xff0c;选择了加密狗驱动&#xff0c;此时要使用软授权就出现了此现象。  解决方法&#xff1a; ① 首先确认软加密驱动正确安装…

XYCTF 部分wp及学习记录

1.ezmd5 根据题目提示 我们知道应该是要上传两张md5值相同的图片 根据原文链接&#xff1a;cryptanalysis - Are there two known strings which have the same MD5 hash value? - Cryptography Stack Exchange 把保存下来的图片上传一下 得到flag 2.ezhttp 根据原文链接&…