树状数组学习笔记
树状数组作为一个常数小且好写的数据结构,虽然功能没有线段树那么齐全,但是其中的扩展内容还是很多的。
1.维护区间和
树状数组可以做到单次 logn 求前缀和,单次 logn 修改信息维护一个前缀和。
1.1 区间修改 单点查询
考虑维护差分数组 \(c[i]=a[i]-a[i-1]\) 。
在查询的部分,一个点的值 \(a[i]\) 将等于 \(\sum\limits_{j=1}^i{c[j]}\) 的值,也就是求前缀和。
修改的话,由于我们要维护的是前缀和,对于一个差分数组来说,显然等价于给 \(l\) 上的点加上 \(v\) , 给 \(r+1\) 上的点加上 \(-v\)。
1.2 区间修改 区间查询
这个部分需要使用两个 BIT 去维护了,设 \(r\) 表示右端点。
首先,由于加法满足结合率,所以可以将区间转化为两端点前缀和之差。
单点的值仍然满足 \(a[i]=\sum\limits_{j=1}^i{c[j]}\) ,因为要求 \(\sum{a[i]}\) ,所以原式子可以写为 \(\sum\limits_{i=1}^r\sum\limits_{j=1}^i{c[j]}\) 。
观察这个式子,不难发现每个 \(c[j]\) 出现了 \(r-j+1\) 次,则原式子又可以写成 \(\sum\limits_{i=1}^rc[i]\times(r+1)-\sum\limits_{i=1}^rc[i]\times i\) 。
因此我们需要开两个 BIT 去单独维护 \(c[i]\) 和 \(c[i]\times i\) 。
第一个好维护,第二个就将 \(l\) 上的点加上 \(v\times l\) , 给 \(r+1\) 上的点加上 \(-v\times(r+1)\) 。
【例题1】 线段树1【模板】 :
点击查看代码
1.3 二维树状数组
既然是二维,那么就有一点类似于树套树,但是常数非常小,空间为 \(n^2\) 。
对于最简单的单点修改,矩阵查询,我们只需要无脑套一层 y 轴方向的循环就好了。
【例题2】 上帝造题的七分钟:
点击查看代码
2. 权值树状数组
所谓权值数组,就是一个桶,\(tr[i]\) 表示的是权值为 \(i\) 的数的个数。
2.1 静态逆序对
静态逆序对问题,暴力做法是对于每一个 \(a_i\) ,找到 \(a_j>a_i\) 且 \(j<i\) ,设这个值为 \(w_i\) 。
但是显然这样的复杂度是 \(O(n^2)\) 的,考虑优化。
考虑加速求 \(w_i\) 的过程。由于是顺着遍历的,所以每求出一个 \(w_i\) ,便可以将这个数丢入桶中,然后再快速地判断原有桶中有多少个数大于 \(a_i\) ,而这个过程,树状数组就可以帮助求和。
如果数字的值非常大或者是小数、负数的话,我们需要离散化处理(或者使用动态开点线段树,总的时间复杂度仍为 \(O(n\log n)\)。
【例题3】 逆序对
点击查看代码
2.2 二维数点
二维数点,顾名思义,给出一个平面内的点集,每次询问一个矩阵内点的数量。
首先,我们先使用容斥,将 \((x1,y1,x2,y2)\) 的询问拆成 \((0,0,x2,y2)+(0,0,x1,y1)-(0,0,x1,y2)-(0,0,x2,y1)\) ,这样就可以把问题转换成点与坐标轴围成区域中所包含的点数量。
考虑对于新询问点的横坐标从小到大排序(点集中的点一样),每次只要是点集中的点横坐标小于询问的横坐标,我们便将这个点的纵坐标加入桶中。处理询问时,我们直接找出桶中小于询问点纵坐标的点的数量就好了,这个过程使用树状数组解决。
二维数点还有很多拓展,当题目要求关键字别分满足某些条件的二元组时,都可以转化为二维数点问题去解决。
【例题4】 老C的任务
点击查看代码
2.3 求解全局第 k 小
由于树状数组特殊的性质,\(tr_i\) 管辖的范围刚好是 \((i-lowbit(i),i]\) 恰好可以减少倍增时候的多余计算。
那么,如果我们要找到一个集合中的第 k 小的数字 \(x\) ,转换为树状数组的语言便是 \(\sum\limits_{i=1}^xtr_i=k\) 。如果每次暴力二分,再用 logn 的复杂度求和,那么时间复杂度将会是 \(O( \log^2 n)\) ,但是如果结合倍增思想,我们就可以省去一些不必要的计算,从而达到 \(O( \log n)\) 的优秀复杂度。
求解 kth 问题的模板
__EOF__

本文链接:https://www.cnblogs.com/fzefze/p/17615051.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)