【树状数组】前缀和问题

news2025/2/28 3:05:03

一、引子

给你一个数组 nums ,请你完成两类查询。

  • 其中一类查询要求更新数组 nums 下标对应的值
  • 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和

题目只是一个用来检测我们思想的东西,比如这道题它也不是前缀和呀?但是我们去仔细去想,区间和可以转化为两个前缀和相减

那可能有同学就要问了,为什么要用前缀和呀,我直接遍历求和不就可以了,是的,如果你的数据量非常小的情况下,是可以直接遍历求和,那你可以退出这篇文章,换言之,数组数组是为了解决大规模数据下的前缀和问题。那么,在我们了解了树状数组所要解决的问题之后,下面就要我们一起来看下树状数组是如何实现的?

二、树状数组

问题: 首先,我们思考一下如果在数据量大的情况下,如何减少遍历数组求前缀和的时间?

答: 我们可以通过另一个数组记录前几个元素的和,比如记录下 1,2 和 2, 3 … 等等数组中元素的和,在求和时,直接拿之前求过的用就行了。

是的,树状数组就是这样一种思想,只不过它是以一种树状的结构将部分元素的前缀和存起来

下图为构造前缀和树状数组图解,大家在看代码的同时,可以结合图解来看,助于理解。

在这里插入图片描述

树状数组有四个关键部分组成,他们分别是:

  • lowbit 函数

lowbit函数结构如,其用来计算数组下标 x 的二进制表示的最后一个1及其后面的0组成的数是多少

        private int lowBit(int x) {
            return x & (-x);
        }

我们需要记住的是,通过 lowbit 函数计算出来的值在树状数组中可以用来表示(x 表示当前节点下标):

1) 2 的 当前节点在树中层数 次幂 = lowbit(x)
2) 当前节点在求前缀和时的下一个累加位置 = x - lowbit(x)

  • 前缀和数组构造函数

在构造前缀和时,我们使用如下的构造函数:

		// 构造函数,用于初始化树状数组
        public NumArray(int[] nums) {
            // 原数组长度+1, +1的原因是计算lowbit时,使用下标0会进入死循环
            this.sums = new int[nums.length + 1];
            this.nums = nums;
            for (int i = 0; i < nums.length; i++) {
                // 初始化累加和数组
                insert(i, nums[i]);
            }
        }

     	// 插入方法
        private void insert(int index, int val) {
            // 下标+1
            int x = index + 1;
            while (x < sums.length) {
                sums[x] = sums[x] + val;
                x += lowBit(x);
            }
        }
  • query 查找函数

query 查找函数用于查找计算 x 位置前缀和需要累加的 sums 数组元素都有那些,对这步不理解的可以去看一下我图解中的那个例子

        /**
         * 查询树状数组, x 为查找的下标,返回值为计算好的前缀和
         */
        public int query(int x) {
            int s = 0;
            while (x != 0) {
                s += sums[x];
                x -= lowBit(x);
            }
            return s;
        }
  • 前缀和数组更新函数

当我们更新某个节点值时,需要对前缀和数组进行更新,更新代码如下:

        /**
         * 更新数组以及累加和,index 为更新位置, val 为更新后的值
         */
        public void update(int index, int val) {
            int x = index + 1;
            while (x < sums.length) {
                // 减去之前nums[index]的值, 加上新的值
                sums[x] = sums[x] - nums[index] + val;
                x += lowBit(x);
            }
            nums[index] = val;
        }

注意点: 为了防止因下标 x = 0 造成的求取 lowbit 时出现无限循环问题,在定义 sums 数组时多定义一位,即使得下标从1处开始。

三、总结

数组数组的思想还是很难的,,尤其是 lowbit 部分,但是对我们来说,会用就行了,只需要记住数组数组几个重要的部分,在求解问题时套用即可

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

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

相关文章

Android BottomSheet总结

文章目录Android BottomSheet总结BottomSheetBottomSheetDialogBottomSheetDialogFragment全屏无阴影BottomSheetDialogFragment代码下载Android BottomSheet总结 BottomSheet XML布局&#xff1a; <?xml version"1.0" encoding"utf-8"?> <an…

C++ 条件变量的使用

绪论 并发编程纷繁复杂&#xff0c;其中用于线程同步的主要工具——条件变量&#xff0c;虽然精悍&#xff0c;但是要想正确灵活的运用却并不容易。 对于条件变量的理解有三个难点&#xff1a; 为什么wait函数需要将解锁和阻塞、唤醒和上锁这两对操作编程原子的&#xff1f;为…

MCMC学习笔记-马尔科夫链概述

参考文章&#xff1a;MCMC(二)马尔科夫链 - 刘建平Pinard - 博客园 写给小白看的马尔科夫链&#xff08;Markov Chain&#xff09;最佳入门教程_许进进的博客-CSDN博客_markov链 目录 1.马尔科夫链概述 1.1股票市场模型 2.马尔科夫链模型状态转移矩阵的性质 (本节重点) 2.…

小程序容器技术加持下,企业自主打造小程序生态

小程序是一种不用下载就能使用的应用&#xff0c;也是一项门槛非常高的创新&#xff0c;经过将近两年的发展&#xff0c;已经构造了新的小程序开发环境和开发者生态。 据对公开资料进行统计&#xff0c;2021年全网小程序数量已超700万&#xff0c;其中微信小程序开发者突破300…

java使用world模板动态生成PDF文件

根据项目需求&#xff0c;需要用到一个功能&#xff0c;根据页面参数需要动态的生成一个world&#xff0c;并将world生成两份PDF文件&#xff0c;一份正式文件&#xff0c;一份临时的电子文件&#xff08;带有二维码&#xff0c;扫描可以下载正式文件的电子版本&#xff09;。同…

JAVA开发(nginx)

主要描述下面4个内容&#xff1a; 1.Nginx的正向代理和反向代理 2.Nginx的动静分离 3.Nginx的负载均衡 4.Nginx的配置详解 解释&#xff1a; Nginx的正向代理&#xff1a;代理的是客户端。 Nginx的反向代理&#xff1a;代理的是服务端。在web服务中&#xff0c;一般都是…

2022年“网络安全”赛项驻马店市赛选拔赛 任务书

2022年“网络安全”赛项驻马店市赛选拔赛 一、竞赛时间 共计3小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段单兵模式系统渗透测试 任务一 Windows操作系统渗透测试 100分钟 100 任务二 Linux操作系统渗透测试 150 任务三 数字取证调查 150 任务四 …

vscode不能打开终端问题

遇到vscode不能打开终端问题&#xff0c;一直以为是安全软件限制问题&#xff0c;也没搜到解决方案&#xff0c;因为影响也不大&#xff0c;就没有管。 最近&#xff0c;要用vscode调试代码&#xff0c;发现不能打开终端&#xff0c;没法玩了&#xff0c;又来看这个问题&#…

【图像隐藏】基于matlab像素预测和位平面压缩的加密图像可逆数据隐藏【含Matlab源码 2218期】

⛄一、加密图像可逆数据隐藏简介 1 信息隐藏技术概述 信息隐藏技术是把秘密信息隐藏在多媒体信息中的一种方法。图像是最适合信息隐藏的数据载体。信息隐藏的方法主要有数字水印技术、隐写术等。 信息隐藏可以分为有损信息隐藏与可逆信息隐藏信息隐藏技术, 区别在于接收端是否…

【虚幻引擎UE】UE5 简单实现范围计算圆圈绘制

先来看看可以实现的效果&#xff1a; 一、实现快速绘制圆圈的C函数 .cpp文件 #include "drawPolygon.h" #include "Components/LineBatchComponent.h" #include "Engine/World.h" #include "EngineGlobals.h" #include "Prim…

墨西哥专线详解:墨西哥专线时效多久,墨西哥专线价格多少?

墨西哥专线是国内直飞墨西哥或者海运墨西哥的专线物流服务&#xff0c;从中国到墨西哥的物流大约需要3到30天。不同的运输方式到墨西哥的时间不同。国际快递是最快的。通常3到5天就可以完成目的地派送&#xff0c;最慢的是海运专线&#xff0c;到墨西哥大约需要20到30天才能到达…

隐式神经表示二:超分网络学习傅里叶系数Local Texture Estimator for Implicit Representation Function

文章目录1. Local Texture Estimator for Implicit Representation Function1. 通过隐式神经网络表示方法 实现 超分辨率。2. 在编码器和解码器之间作者引入一个 local texture estimator3. 代码分析整体框架生成图像特征&#xff0c;编码器是一个常规的卷积网络&#xff0c;文…

【Pytorch with fastai】第 8 章 :协同过滤深入探讨

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

十四、Java String 类

Java String 类 字符串广泛应用 在 Java 编程中&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 创建字符串 创建字符串最简单的方式如下: String str "xxx"; 在代码中遇到字符串常量时&#xff0c;这里的值是 &q…

大数据开源平台好在哪里?

当前是大数据发展时代&#xff0c;对于企业而言需要紧紧抓住契机乘势而上&#xff0c;利用好内部数据做好数字化转型&#xff0c;可以为企业带来更高的发展空间。大数据开源平台是助力企业提升办公效率的软件平台&#xff0c;那么&#xff0c;哪里有这样的大数据开源平台&#…

关于Git使用:fatal: Could not read from remote repository.的报错问题解决

目录 一&#xff1a;问题描述 二&#xff1a;解决过程 1&#xff0c;增加账号及邮箱 2&#xff0c;添加秘钥&#xff1a; 3&#xff0c;获取公钥并将其设置到云效里面 4&#xff0c;宝塔终端 解除密码 三&#xff1a;解决截图 一&#xff1a;问题描述 我们公司的版本仓…

【布隆过滤器】世界上大概有1 亿种小蛋糕,客户康宝要求这辈子不吃重复的小蛋糕。

文章目录需求概念思想问题优点缺点应用手写布隆过滤器补充需求 现在客户康宝有一个需求&#xff1a;世界上大概有 1 亿 种小蛋糕&#xff0c;康宝要求这辈子不吃重复种类的小蛋糕。 因为小蛋糕的种类很大可能只会增加&#xff0c;而不会减少&#xff0c;面对这种大数据量的要…

静态分析 Qt Ceator 组织的工程代码

文章目录Missing reference in range-for with non trivial type (QString) [clazy-range-loop]Slots named on_foo_bar are error prone [clazy-connect-by-name]Call to virtual method FlowLayout::takeAt during destruction bypasses virtual dispatch [clang-analyzer-op…

目的和目标的差异|丰田自动工程完结的目的、目标、应用化的意义和明确、二

目的和目标的差异|丰田自动工程完结的目的、目标、应用化的意义和明确、二 业务的方式改废|工作的目的、目标、输出的明确化 业务改善的一种方法被称为业务改废。意思是更好地改善现有的业务&#xff0c;废除不必要的业务。 使用这种方法&#xff0c;首先要明确想要改变和废除…