(C++) 树状数组

news2024/11/13 12:38:40

目录

一、介绍

二、一维树状数组

        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://www.coloradmin.cn/o/1617335.html

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

相关文章

火绒安全概述

页面简介&#xff1a; 火绒安全是一款集多种安全功能于一体的国产软件&#xff0c;旨在为用户提供全面的计算机保护。本页面将详细介绍火绒安全的核心功能和使用方式。 页面内容概览&#xff1a; 杀毒防护 实时监控&#xff1a;详细介绍火绒安全如何实时检测系统中的文件和程序…

Pyside6:Spacer的使用,布局中控件顶格添加

在普通的布局&#xff0c;如水平或纵向布局中&#xff0c;我们的控件都会保持中间状态&#xff0c;如下&#xff1a; 但有许多情况下 &#xff0c;我们需要将控件布局为如下界面&#xff1a; 在前端开发时&#xff0c;我们很容易通过flex来进行布局&#xff0c;修正它的居中或者…

Github首页美化(updating)

Github首页美化 https://github.com/QInzhengk一、新建仓库二、美化Github首页主页访问量统计仓库状态统计常用语言占比统计社交链接 界面展示 https://github.com/QInzhengk 一、新建仓库 对Github首页进行美化&#xff0c;需要新建一个仓库名和自己 Github 用户名相同的仓库…

【数据库】三、数据库SQL语言命令(基础从入门到入土)

【全文两万多字&#xff0c;涵盖大部分常见情况&#xff0c;建议点赞收藏】 目录 文章目录 目录安装SQL语言1.使用2.DATABASE查看所有库新建数据库修改数据库删除数据库连接数据库 3.TABLE创建表查看库所有表删除表查看表信息重命名表修改表字段&#xff08;列&#xff09;表中…

Java---ideaIU-2023.1专业版使用以及安装方法

介绍 JetBrains 是一家专注于创建智能开发工具的前沿软件公司,包括:行业中领头的 Java IDE – IntelliJ IDEA,以及 Kotlin 编程语言。旗下常用的软件有IntelliJ IDEA、PhpStorm、RubyMine、Rider、WebStorm、goland、CLion、Pycharm&#xff0c;本安装包集成以上8款软件&#…

最大层内元素和

题目链接 最大层内元素和 题目描述 注意点 返回层内元素之和 最大 的那几层&#xff08;可能只有一层&#xff09;的层号&#xff0c;并返回其中 最小 的那个树中的节点数在 [1, 10000]范围内-10^5 < Node.val < 10^5 解答思路 广度优先遍历树&#xff0c;使用队列存…

windows系统CUDA的详细安装教程

CUDA系列 文章目录 CUDA系列前言一、CUDA简介二、安装配置视频教程三、CUDA的下载及安装3.1 环境检查3.2 CUDA 安装包下载3.3 安装CUDA&#xff08;略&#xff09;3.4 验证CUDA是否安装成功 四、cuDNN的下载及安装4.1 cuDNN下载4.2 cuDNN配置 五、配置环境变量六、下载并配置zl…

Day4 商品管理

Day4 商品管理 这里会总结构建项目过程中遇到的问题&#xff0c;以及一些个人思考&#xff01;&#xff01; 学习方法&#xff1a; 1 github源码 文档 官网 2 内容复现 &#xff0c;实际操作 项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目 编写品牌服务 …

LangChain入门指南:构建高可复用、可扩展的LLM应用程序 PDF书籍分享

今天又来给大家推荐一本大模型方面的书籍<Langchain入门指南>这本书专门为那些对自然语言处理技术感兴趣的读者提供了系统的LLM应用开发指南。全书分为11章&#xff0c;从LLM基础知识开始&#xff0c;通过LangChain这个开源框架为读者解读整个LLM应用开发流程。 下载当前…

轻松记录收支明细,详细记录每一笔收支,通过借款日期快速查找借款信息

财务管理对于个人和企业来说都至关重要。一份清晰、详尽的收支明细记录&#xff0c;不仅能帮助我们了解资金流向&#xff0c;还能在需要时提供有力的证据。因此&#xff0c;高效记录收支明细并轻松掌握财务状况成为了每个人的必备技能 第一步进入晨曦记账本主页面&#xff0c;…

ros2_control【B站WMGIII教学学习记录】1

资源 https://www.bilibili.com/video/BV1ku411G7UR? 学习过程中存在bug&#xff0c;记录一下 1 Q:"package ‘joint_state_publisher_gui’ not found, searching: [/home A: sudo apt install ros-humble-joint-state-publisher2 https://fishros.org.cn/forum/to…

抢先看!LEADTOOLS V23 全新版发布,预览全新产品线布局!

LEADTOOLS (Lead Technology)由Moe Daher and Rich Little创建于1990年&#xff0c;其总部设在北卡罗来纳州夏洛特。LEAD的建立是为了使Daher先生在数码图象与压缩技术领域的发明面向市场。在过去超过30年的发展历程中&#xff0c;LEAD以其在全世界主要国家中占有的市场领导地位…

SpringCloud引入SpringBoot Admin

Spring Boot Admin可以监控和管理Spring Boot&#xff0c;能够将 Actuator 中的信息进行界面化的展示&#xff0c;也可以监控所有 Spring Boot 应用的健康状况&#xff0c;提供警报功能。 1. 创建SpringBoot工程 2. 引入相关依赖 <dependency><groupId>com.alib…

基于ontape的备份与恢复实验

通过本文的备份恢复实验&#xff0c;我们可以深入了解ontape的使用方法和原理&#xff0c;包括如何进行完整备份、增量备份以及如何利用备份文件进行数据恢复。 1. 配置onconfig参数 通过修改onconfig参数文件&#xff0c;或使用onmode -wf命令&#xff0c;设置备份默认使用的…

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

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

DSP系统的设计过程与选型

DSP的设计步骤分几个阶段&#xff0c;应用系统的设计过程如图所示。 技术指标的确定 器件的选型原则 其他因素的考虑

谈谈mysql中的各个关键字

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

第G8周:ACGAN任务

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 参考论文 这周主要任务就是根据之前GAN&#xff0c;CGAN&#xff0c;SGAN网络架构搭建…

OpenStack云计算(十一)——OpenStack网络管理,验证OpenStack网络资源模型,验证来巩固和加深对OpenStack网络资源模型的理解

项目实训一 【实训题目】 验证OpenStack网络资源模型 【实训目的】 通过验证来巩固和加深对OpenStack网络资源模型的理解。 【实训准备】 &#xff08;1&#xff09;复习Neutron网络资源模型。 &#xff08;2&#xff09;重点理解网络、子网、端口和路由器的概念。 【实…

使用LLM-API开发应用-DataWhale笔记

调用API 先使用一个例子 from openai import OpenAI ​ client OpenAI(# This is the default and can be omittedapi_keyos.environ.get("OPENAI_API_KEY"), //这个在环境env中 ) ​ completion client.chat.completions.create(# 调用模型&#xff1a;ChatGPT-…