前缀和的动态维护——树状数组[C/C++]

文章目录

    • 前言
    • lowbit
      • lowbit的定义
      • lowbit的计算
    • 树状数组的思想
    • 树状数组的操作
      • 单点修改 update
      • 前缀查询 query
      • 树状数组的建立 build

前言

树状数组巧妙了利用位运算和树形结构实现了允许单点修改的情况下,动态维护前缀和,并且实现单点修改和前缀和查询的效率的很可观。树状数组也可以对差分数组维护前缀和来实现区间修改区间查询,但由于过于繁琐,对于区间查询往往用线段树来代替,但树状数组以其简洁的代码实现成为了动态维护前缀和的不二选择。

lowbit

在介绍树状数组前需要先了解lowbit的概念,其作用会在后面树状数组中具体解释。

lowbit的定义

非负整数n在二进制表示下最低位1以及其后面的0构成的数值

例如: 44d = 10 1100b ,那么lowbit(44) = (100)b = 4(d)

lowbit的计算

我们手算补码的时候有一个技巧就是从符号位的下一位开始一直取反,到最后一个1的时候不对其取反然后停止,因为非符号位取反加一后原先的最后一个1又会变成1,于是我们可以利用这个技巧来快速的求lowbit。

我们将x和~x + 1做与运算就会得到lowbit,因为计算机中对一个数字取反后连符号位都会取反,而一个数字取反+1后原先的最低位1以及其后面的0不受影响,所以x 和 ~x + 1的公共部分就是lowbit

故有lowbit(x) = x &(~x + 1)

即然我们说了计算机中直接取反会对符号位也取反,那么~x + 1就会得到其相反数的补码,而计算机中以补码存储数字,故上面的式子可改进为lowbit(x) = x & -x

树状数组的思想

**树状数组(Binary Indexed Tree)**既然叫树状数组,那么它是怎么将数组抽象成树形结构的呢?

其实和汉明码类似,lowbit其实就是二进制的第一位为1、第二位为1、第三位为1…

而对于1到n这n个数字我们如果取二进制表示下含lowbit(x)的数字,我们发现这些数字正好是若干个长度为lowbit(x)的连续序列组成每个序列间的间隔也是lowbit(x)

我们按照lowbit划分层次,每层以lowbit(x) * 1 ,lowbit(x) * 2 ,lowbit(x) * 3…结尾的长度为lowbit(x)的连续序列作为该层的节点,同时我们以t[ i ]代表当前层第i个序列的元素之和

而我们要维护前缀和的原序列就成了我们的叶子节点

于是有了下图的树形结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这棵树有如下特点:

  • t[x]保存以x为根节点的子树中叶节点值的和
  • t[x]节点的长度等于lowbit(x)
  • t[x] 的父节点为t[x + lowbit[x]]
  • 整棵树的深度为logn + 1
  • 我们发现t[x]满足如下公式:

t [ x ] = ∑ i = x − l o w b i t ( x ) + 1 x a [ i ] t[x] = \sum_{i = x - lowbit(x) + 1}^{x}a[i] t[x]=i=xlowbit(x)+1xa[i]

树状数组的操作

由于区间修改我们有更适合的数据结构——线段树,所以我们就不介绍树状数组维护差分数组实现区间修改的操作了。

单点修改 update

当我们给一个叶子节点x增加k,那么需要对其父节点开始往上更新,而x父节点就是x + x & -x,所以一层循环就能搞定

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

void update(int x, int k)
{for (; x <= n; x += x & -x)t[x] += k;
}

时间复杂度O(logn)

前缀查询 query

查询前x个元素的前缀和,我们从图上看发现我们只需要从t[x]往左上的第一个节点走,路径上节点的值之和就是前x个节点的前缀和

而找到左上第一个节点我们只需要减去当前节点的lowbit值即可

而减去lowbit其实就是把最低位1置为0,而把最低位1置位0我们还可以通过x &= (x - 1)来实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

int query(int x)
{int sum = 0;for (; x > 0; x &= (x - 1))sum += t[x];return sum;
}

树状数组的建立 build

前面谈了单点修改和前缀查询,那么给定一个长度为n的数组我们如何建立树状数组呢?

暴力做法:进行n次插入操作,时间复杂度O(nlogn)

虽然可行,但是我们发现n次插入过程中其实是有冗余操作的,我们每次插入都会一直向上更新到根节点,但是我们这个过程可以等效为每次完成一个节点值的计算都对其父节点进行更新,这样最后我们的每个节点的值都是正确的,而且也只对数组遍历了一次,实现了O(n)建树

代码如下:

void build(const vector<int> &arr)
{for (int i = 1; i <= n; i++){t[i] += arr[i];t[i + (i & -i)] += t[i];}
}

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

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

相关文章

【JavaEE】操作系统与进程

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

python 水质日历热力图

利用日历热力图可以方便的查看站点水质全年的变化情况。 接口获取站点数据 这一步根据自己实际情况&#xff0c;也可以读取excel、MySQL读取数据。这里把API地址已隐去。 import numpy as np import calendar import requests import json import pandas as pd import time f…

给定两个字符串 s 和 t ,找不同

题意&#xff1a; 给定两个字符串 s 和 t &#xff0c;它们只包含小写字母。 字符串 t 由字符串 s 随机重排&#xff0c;然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。 示例 1&#xff1a; 输入&#xff1a;s “abcd”, t “abcde” 输出&#xff1a;“e”…

【python学习】基础篇-常用第三方库-psutil:用于获取CPU、磁盘与网络等系统信息和进程管理

psutil是一个跨平台的Python库&#xff0c;用于获取系统信息和进程管理。以下是一些基本的用法&#xff1a; 获取CPU使用率 cpu_percent psutil.cpu_percent(interval1) print(cpu_percent)获取内存使用情况 memory_info psutil.virtual_memory() print(memory_info.perce…

Linux:进度条(小程序)以及git三板斧

Linux小程序&#xff1a;进度条 在实现小程序前我们要弄清楚&#xff1a; 1.缓冲区&#xff1b; 2.回车与换行。 缓冲区&#xff1a; 分别用gcc来编译下面两个程序&#xff1a; 程序一&#xff1a; #include <stdio.h> int main() { printf("hello Makefil…

前后端分离SpringBoot+vue的买菜农副产品多功能商城

1&#xff0c;项目介绍 本系统主要针对买菜而设计&#xff0c;其功能有菜品基本信息管理、商品类别管理、系统订单管理、评论管理、系统用户管理等功能模块。并且本系统采用了现在流行的SpringBootVue进行的设计与实现&#xff0c;其中Tomcat为服务器&#xff0c;MySQL为数据库…

QT中的lambda表达式

面是对Qt中在QObject::connect()中的lambda表达式常用用法 QString str("I am a string!"); devicestr; connect(ui- connect(m_imgshowUI, &ImgShow::GetImgPath, m_visionplatform, [](const std::string filename){m_visionplatform->ReadImg(filename);}…

moviepy 视频剪切,拼接,音频处理

官网 使用matplotlib — moviepy-cn 文档 案例 from moviepy.editor import * from moviepy.video.fx import resize from PIL import Imagefile1r"D:\xy_fs_try\video_to_deal\spider_video\file\vedeo3.mp4" file2r"D:\xy_fs_try\video_to_deal\spider_video\…

Maven聚合项目发布至私服指定模块

无论是从事框架开发工作还是公共服务模块开发&#xff0c;为了解决通用性问题&#xff0c;常常需要发布一些依赖组件至maven私服。然而通常我们得maven工程都是由多个模块组成得聚合工程&#xff08;一个父工程下有多个模块&#xff09;。 这个时候可能会面临两个窘境&#xf…

小红书干货类笔记怎么写?建议收藏

小红书干货类笔记是指在小红书这个社交平台上&#xff0c;用户分享的各种实用、有价值的生活技巧、经验、心得等内容的笔记。这类笔记通常具有以下特点&#xff1a;内容详实、实用性强、独特见解、图文并茂。 比如&#xff1a;某个妆要怎么化、某种技能该怎么学、某个城市该怎…

java实现一个简单的监听器

在 Java 中&#xff0c;我们可以通过实现监听器&#xff08;Listener&#xff09;模式来处理事件和回调。监听器模式是一种常见的设计模式&#xff0c;用于实现对象间的松耦合通信。本文将介绍如何在 Java 中实现一个简单的监听器。 步骤 以下是实现一个监听器的基本步骤&…

关于input直接上传文件夹

用最基础的input 就可以实现 <input type"file" webkitdirectory directory"" /> 如果是像点击按钮之后上传文件夹可以这样写 <el-button type"primary" style"margin-top: 30px;width: 170px;" click"importModel&qu…

教你ehco、date、sep命令如何使用

echo命令 echo -n 表示不换行输出 echo -e 表示输出转义符 常用的转义符 选项 作用 \r 光标移至行首&#xff0c;并且不换行 \s 当前shell的名称&#xff0c;如bash \t 插入Tab键&#xff0c;制表符 \n 输出换行 \f 换行&#xff0c;但光标仍停留在原处 \ 表…

【开源】基于JAVA的开放实验室管理系统

项目编号&#xff1a; S 013 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S013&#xff0c;文末获取源码。} 项目编号&#xff1a;S013&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…

GPS北斗卫星同步时钟系统(北斗授时设备)在通信系统中应用

GPS北斗卫星同步时钟系统(北斗授时设备)在通信系统中应用 GPS北斗卫星同步时钟系统(北斗授时设备)在通信系统中应用 卫星时间同步系统是根据《华东电网统一时钟系统技术规范》、《上海电网GPS时间同步系统技术原则和运行管理规定》和《电力系统时间同步技术规范》设计的时间同步…

【Vue】生命周期一文详解

目录 前言 生命周期 钩子函数使用方法 ​编辑 周期-----创建阶段 创建阶段做了些什么事 该阶段可以干什么 周期----挂载阶段 挂载阶段做了什么事 该阶段适合干什么 周期----更新阶段 更新阶段做了什么事 该阶段适合做什么 周期----销毁阶段 销毁阶段做了什么事 …

C++:继承

一、继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的层次结构&#xff0c…

使用Microsoft Dynamics AX 2012 - 4. 销售和配送

销售和分销的主要职责是为客户提供您的商品和服务。为了完成这项任务&#xff0c;销售和分销需要通过分拣、运输和开具发票来处理销售订单&#xff0c;从而管理客户的材料需求。 销售和配送业务流程 在我们开始详细介绍之前&#xff0c;下面几行概述了销售和配送中的业务流程…

【IEEE独立出版 | 往届均完成检索】2024年第四届消费电子与计算机工程国际学术会议(ICCECE 2024)

#国际学术会议# 推荐 #广州# 【IEEE独立出版 | 往届均完成检索】2024年第四届消费电子与计算机工程国际学术会议&#xff08;ICCECE 2024&#xff09; 2024 4th International Conference on Consumer Electronics and Computer Engineering 2024年1月12-14日 | 中国广州 会…