树状数组详解(区间修改和单点查询)

树状数组原理详解:从前缀和到lowbit,单点修改区间查询的O(log n)利器 在算法与数据结构学习中,前缀和能高效处理静态区间求和,但面对高频单点修改时却面临O(n)更新的瓶颈。树状数组(Fenwick Tree)通过二进制lowbit机制,将数组下标按最低位1划分为若干管辖区间,使得单点修改和前缀查询都能在O(log n)时间内完成。其核心思想在于:利用整数二进制位数有限这一天然约束,将原本线性的更新链压缩为不超过log n次的跳跃路径。这种结构不仅代码极短、常数小,更在离散化、逆序对统计、动态第k小等场景中成为经典解法。理解树状数组的二进制下标设计,是掌握这一高效数据结构的关键入 阅读详情

前置芝士

单点修改和区间查询

引入

先看例题:(洛谷 P3368 【模板】树状数组 2)

已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数数加上 x x x
2.求出某一个数的值。

这题和 树状数组1 有什么区别?

没错,正如题目所说,这题是区间修改和单点查询!

区间修改和单点查询

区间修改和单点查询要怎么实现呢?这需要用到一个东西:差分。

差分是什么呢?(知道的大佬可以跳过)

对于一个数组 a [ ] a[] a[],我们设它的差分数组为 b [ ] b[] b[],则满足:

b [ 1 ] = a [ 1 ] b[1]=a[1] b[1]=a[1]
b [ i ] = a [ i ] − a [ i − 1 ] ( 1 < i ≤ n ) b[i]=a[i]-a[i-1](1<i≤n) b[i]=a[i]−a[i−1](1<i≤n)

那这有什么用呢?我们可以发现一个性质:

a [ i ] = ∑ k = 1 n b k a[i]=\sum\limits_{k=1}^n b_k a[i]=k=1∑n​bk​

联系一下树状数组,你想到了什么?

对了!可以把单点查询转化为差分数组的区间查询!

那么区间修改又怎么解决呢?别着急,我们来看第二个性质:

我们设一个数组 a [ ] a[] a[]及它的差分数组 b [ ] b[] b[]为:

a [ ] a[] a[] 1 1 1 4 4 4 5 5 5 7 7 7 8 8 8 3 3 3 1 1 1
b [ ] b[] b[] 1 1 1 3 3 3 1 1 1 2 2 2 1 1 1 − 5 -5 −5 − 2 -2 −2

我们对 a [ ] a[] a[]进行区间修改,将 a [ 3 ] a[3] a[3]~ a [ 5 ] a[5] a[5]的值加上 2 2 2,可以得到:

a [ ] a[] a[] 1 1 1 4 4 4 7 7 7 9 9 9 10 10 10 3 3 3 1 1 1
b [ ] b[] b[] 1 1 1 3 3 3 3 3 3 2 2 2 1 1 1 − 7 -7 −7 − 2 -2 −2

观察 b [ ] b[] b[]的变化,你发现了什么?

只有 b [ 3 ] b[3] b[3]和 b [ 6 ] b[6] b[6]发生了变化! b [ 3 ] b[3] b[3]加上了 2 2 2, b [ 6 ] b[6] b[6]加上了 − 2 -2 −2!

经过多次试验,我们可以得到这样一个性质:

将 a [ l ] a[l] a[l]~ a [ r ] a[r] a[r]加上 k k k,等价于将 b [ l ] b[l] b[l]加上 k k k,将 b [ r + 1 ] b[r+1] b[r+1]加上 − k -k −k。

再联系一下树状数组,你又想到了什么?

我们可以将区间修改转化为差分数组的单点修改!

这样,我们就将区间修改和单点查询转化为了我们熟悉的单点修改和区间查询!问题迎刃而解了!

完整代码

#include<iostream>
#include<cstdio>
#define MAXN 500010
using namespace std;
int n,m,op,x,y,k;
int a[MAXN],c[MAXN];
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,int k)
{
	for(;x<=n;x+=lowbit(x))
		c[x]+=k;
}
int query(int x)
{
	int res=0;
	for(;x>=1;x-=lowbit(x))
		res+=c[x];
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		update(i,a[i]-a[i-1]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%d",&x,&y,&k);
			update(x,k);
			update(y+1,-k);
		}
		else
		{
			scanf("%d",&x);
			printf("%d\n",query(x));
		}
	}
	return 0;
}
树状数组实现区间修改与单点查询的算法解析 树状数组(Binary Indexed Tree)是一种高效处理动态前缀和问题的数据结构,广泛应用于算法竞赛和大规模数据处理场景。其核心原理是通过二进制索引实现O(log n)时间复杂度的单点更新和前缀查询。结合差分数组技术,可以扩展出区间修改功能,这在处理批量数据更新时尤为重要。本文以经典题目P3368为例,详细讲解如何通过差分思想改造标准树状数组,实现高效的区间增量操作和精确单点查询。该技术在实时数据监控、金融交易系统等需要频繁区间更新的场景中具有重要应用价值,特别是在NOIP/CSP等编程竞赛中,这种 阅读详情

相关推荐

【树状数组】【单点修改区间求和】【区间修改单点查询】【单点修改区间最大值查询】

树状数组:

曾经追梦的happy时光 1167

树状数组(单点修改,区间修改等)

单点修改,区间查询;区间修改,单点查询;区间修改,区间查询;

issey的博客 2854

高德地图JS API私有化部署实战:从数据爬取到内网集成

本文详细介绍了高德地图JS API私有化部署的完整流程,涵盖从地图瓦片数据爬取、JS API离线化改造到内网项目集成的实战步骤。重点解决了在封闭内网环境中实现地图功能的核心难题,并提供了Vue.js项目中的具体集成代码与调试技巧,帮助开发者在离线环境下构建稳定可靠的地图应用。

weixin_29062255的博客 318

树状数组(1.单点修改,区间查询 2.区间修改,单点查询)

一种较高级的数据结构——树状数组,综合降低了数组中修改和查询操作的复杂度,相比于线段树,代码实现更为简短且易理解。

weixin_53024141的博客 2763

模型检测--工具KeYmaera

论文:KeYmaera: A Hybrid Theorem Prover for Hybrid Systems 作者:Andre Platzer and JanKeYmaera摘要1 介绍2用于混合系统的KeYmaera验证工具3混合系统,混合自动机和混合程序 摘要 KeYmaera是一种用于混合系统的混合验证工具,它结合了演绎,实数代数和计算机代数证明者技术。它是自然的自动和交互式定理证明器 混合系统的规范和验证逻辑。 KeYmaera支持差分动态逻辑,它是用于混合程序的实值一阶动态逻辑,是混合自动机的程

ziigea的博客 1077

告别Vivado自带编辑器!手把手教你用Sublime Text 4 + Icarus Verilog搭建FPGA开发环境(Windows 10/11)

本文详细介绍如何在Windows 10/11系统下,使用Sublime Text 4和Icarus Verilog搭建高效的FPGA开发环境,替代Vivado自带编辑器。通过配置语法检查、代码高亮和智能补全等功能,提升Verilog开发效率,实现专业级工作流。

weixin_30684743的博客 427

树状数组--单点修改与区间查询、单点查询与区间修改【模板】

介绍树状数组的基础应用--单点修改与区间查询

Silver_Bullet的博客 350

基于STM32与ESP8266的MQTT协议实现阿里云物联网平台远程LED控制

本文详细介绍了如何利用STM32单片机与ESP8266 Wi-Fi模块,通过MQTT协议连接阿里云物联网平台,实现远程控制LED灯的完整物联网项目。内容涵盖硬件连接、阿里云平台配置、MQTT协议与AT指令解析、STM32代码实战以及数据解析与调试技巧,为嵌入式开发者提供了一个清晰、实用的物联网入门实践指南。

svm4gardener的博客 791

树状数组(单点修改+区间查询)

acwing算法提高课-数据结构-树状数组。

weixin_66430194的博客 874

实战案例—encrypt靶场(AES固定key篇)

AES是一种对称密钥加密方法,意味着加密和解密时使用相同的密钥。AES加密存在三种形式:AES-128、AES-192和AES-256,它们分别对应于三种不同的密钥长度——128位(即16字节)、192位(即24字节)和256位(即32字节)。通常情况下,密钥的长度越长,提供的安全性就越高,但相应地,加解密过程所需的时间也会增加。默认情况下,采用的是AES-128,其提供的安全性对于大多数应用来说已经足够充分。

zhouzhou_98的博客 497

SAP Event Mesh 简介

Get Started with Messaging for Decoupled Communication Step 1: What is the SAP Event Mesh service? SAP Event Mesh 是一种完全托管的服务,用于连接应用程序、服务和系统,以便它们可以通过消息和事件相互交互。 它通过引入中央消息代理取代了传统的点对点通信。 虽然点对点通信适用于在有限数量的发送方和接收方之间共享数据,但可扩展性很快就会成为一个问题。 SAP Event Mesh 解决了这个问题,并确保

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1242

树状数组(单点修改+单点查询+区间修改+区间查询)

树状数组(单点修改+单点查询+区间修改+区间查询)

水,全都是水 3223

LangGraph-StateGraph 和 Graph API 源码分析

摘要: StateGraph是LangGraph的核心API,用于构建有状态工作流图。本文分析了其实现原理,包括: 核心类关系:StateGraph(构建器)和CompiledStateGraph(继承自Pregel的可执行图) 关键流程:状态模式到通道的映射、节点到PregelNode的转换 实现特点: 支持TypedDict和Pydantic两种状态模式 自动选择通道类型(LastValue或BinaryOperatorAggregate) 通过映射函数处理节点输入输出 边实现基于通道写入机制 编译过程

838

树状数组详解(单点修改和区间查询)

我们来看下面的例题: 已知一个数列,你需要进行下面两种操作: 1.单点修改:将某一个数加上 x 2.区间查询:求出某区间每一个数的和 我们有哪些方法呢? 暴力。单点修改的时间复杂度为O(1),区间查询的复杂度为O(n)。 前缀和。单点修改的时间复杂度为O(n),区间查询的复杂度为O(1)。 我们可以看到,两种做法都有一个操作是O(1)的,但也都有一个操作是O(n)的。 那有没有什么两全其美的做法呢?当然有了。有的人可能就会喊了:线段树! 线段树固然好,但它也有它的缺点:算法常数大,编写难度高。 那就

Wu_while的博客 1108

AMDGPU驱动中Doorbell与Event机制简要对比

摘要:AMDGpu驱动中,Doorbell和Event是两种异步通知机制。Doorbell是CPU→GPU的单向硬件通知,通过写MMIO寄存器触发GPU拉取任务,延迟低且无需内核介入,适用于队列任务提交。Event是GPU→CPU的双向同步通知,基于中断和内核事件对象,支持阻塞等待,用于任务完成或异常上报。核心区别在于方向、用途和实现方式:Doorbell侧重任务触发,Event侧重状态反馈。两者配合实现高效的任务下发与完成通知流程。

图形/计算GPU的驱动与虚拟化技术分享园地 1850

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[算法]树状数组

前言 相信大家都会树状数组的"单点修改,区间查询"或者"区间修改,单点查询",博主就不细讲了。 但是博主今天发现了一个神奇的算法(博主太菜),它可以使用树状数组维护"区间修改,区间查询"。 单点修改,区间查询 就是一个优化过的前缀和,使查询和修改协调为\(\Theta(log_2n)\) 代码 namespace FenTree{ #define lowbit(x) (x&-x) ...

weixin_30662011的博客 86

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

HDU1166,敌兵布阵(树状数组)

树状数组的模板题。 树状数组是一个查询和更新复杂度都为log(n)的数据结构。主要用于数组的单点修改&&区间求和。 关于树状数组的详解,可看下面的博客: https://blog.youkuaiyun.com/bestsort/article/details/80796531#区间修改-单点查询 核心是在lowbit函数上。 此题为树状数组的单点更新与区间求和问题。 代码如下: #includ...

shamansi99的博客 165

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Dalamud 指南:FFXIV 插件框架完整解析与第一个插件快速上手

Dalamud 是《最终幻想XIV》(FFXIV)的插件开发框架,为插件提供游戏数据访问和游戏原生内存互操作(native interop)能力。它解决的核心问题是:游戏客户端的界面与功能都是封闭的,你无法给战斗界面加统计、无法自定义 UI 布局、无法用脚本读取聊天日志。Dalamud 把这些数据开放出来,让你用 C# 写出跑在游戏进程内的插件。如果你是玩家,它托管第三方插件;如果你是新手开发者,

gitblog_00702的博客 64

树状数组详解!

【详解】最详细的树状数组解析!!!一遍就懂

Salute 356

树状数组(单点修改&&区间查询、区间修改&&单点查询、区间修改&&区间查询)

今天看了一下树状数组,个人认为树状数组是一个很优美的数据结构,虽然看的并不是很懂。。。一些简单的知识就不讲的,请自行百度。。不过还是讲一些最基础的吧。 概述 树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组{a}中的元素可能不断地被修改,怎样才能快速地获取一个区间的和? 树状数组基本...

ityanger的技术栈 8059

树状数组(单点修改区间查询、区间修改单点查询、区间修改区间查询)

Description如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和Input第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x k 含义:将第x个数加上k 操作2: 格式

Zaaaaars19 5931

树状数组(单点修改和区间查询问题)

今天刚学了树状数组,理解还不是很透彻,写点东西加深理解、记忆 树状数组的结构(C数组表示树状数组,A数组表示普通的数组) 先给出几个概念和性质 lowbit:顾名思义,将一个十进制数转换为二进制,最低位1所对应的值就是该数的lowbit值。lowbit(a)=(a&(-a))例如5转换为二进制数为101,最低位1对应的值为1,那么lowbit(5)就是1。其实如果这个二进制数末尾...

陈颜的博客 5254

树状数组 --区间查询+区间修改

数据结构

ACoder 1万+

树状数组(单点修改+区间修改)

【引入】 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个数组的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。 这种数据结构(算法)并没有C++...

菜鸡成长史 3857

树状数组详解(区间修改和区间查询)

前置芝士 单点修改和区间查询 区间修改和单点查询 引入(洛谷 P3372 【模板】线段树 1) 已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上 kkk。 2.求出某区间每一个数的和。 这是线段树的模板题,然而我们要用树状数组去做它! 可以看出这题就像是 单点修改区间查询 和 区间修改单点查询 的升级版,好,那我们就顺着这两道题的思路继续走。 区间修改和区间查询 我们还是利用差分,可以得: ∑i=1nai=∑i=1n∑j=1ibj=n×b1+(n−1)×b2+...+bn=n×∑i=1n

Wu_while的博客 3656

树状数组详解!(C++_单点/区间查询_单点/区间修改)

先把这张著名的树状数组结构图摆在最前面,接下来我们就以这张图讲起!        首先图中的A数组就是所谓的原数组,也就是普通的数组形态,C则是我们今天要说的树状数组(可以看出一个数的形状,但其实和树没多大关系) 从图中可以明显看到以下几个式子: C[1]=A[1];C[1]=A[1];C[1]=A[1]; C[2]=C[1]...

ccql's Blog 1351
上一篇: 单调队列优化DP
下一篇: 树状数组详解(区间修改和区间查询)
Wu_while
博客等级 码龄6年 50粉丝 53原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值