【c++提高1】树状数组

大纲

1.树状数组简述
2.树状数组的思想
3.基础问题的扩展:树状数组求任意区间
4.树状数组代码实现

1.树状数组简述

树状数组是一个可以实现"单点修改与区间查询或者单点查询与区间修改"只用O(logn)复杂度完成的一个数据结构,说起来它的作用和线段树十分的相似哈,不过它的空间是比线段树少的,并且线段树的常数比较大,所以在可以不用线段树、用树状数组可以解决的问题时还是用树状数组比较好,并且树状数组的代码少。但是对于只有线段树可以解决,树状数组解决不了的问题时只能用线段树了没办法。
话不多说,继续。

2.树状数组的思想

想要了解树状数组的工作原理,我们可以先从一个简单的问题开始想。
问题:

给定10^6个数,也就是一个数组,现在需要你实现两个功能:
1.修改单个元素
2.查询数组中1~x中所有元素的总和
接下来有10^5个操作或询问,每次也就是这两个功能中的任意一个,应该能理解吧。

如果这道题的数字数量小一些的话那么可以直接模拟题目,即用数组存,然后修改时直接赋值,查询就遍历一下者段区间记录总和。可惜的是这道题有10 ^ 6个数,但是一次询问都要最多10 ^ 6的复杂度了,题目在造全是询问1 ~ 10^6的数据卡你的话直接tle没得说。
所以呢我们需要用一些巧的方法来优化。
现在我们两两一组做一个数组b,b[i]存储的是第i对也就是2i-1个数和2i个数的对的总和,这样的话统计的时候复杂度可以减半,并且在单点修改的时候只是需要修改两个也就是那个点处在的对也就是b数组中它在那个下标的b[i]的对中和a数组里的这个点的值。
在这里插入图片描述继续深入,我们在把刚才的b数组两两求和配对,即为数组c,这样和刚才非常像,这样查询的时候可以时间减半也就是原来复杂度除以4,原理和刚才的一样,是应为原来需要消耗O(4)时间复杂度的一个长度位4的段现在可以在c数组中O(1)解决。修改的时候就是把a,b,c与需要修改的下标对应的位置修改一下值即可。
在这里插入图片描述按照这个思路我们可以把它总结位一棵树,树的根节点是我们这个方法的最终产物:所有树的总和,他是通过下面两个长度是它的一半的和相加产生的。
在这里插入图片描述
这样的话时间复杂度优化了许多。
举个例子:
现在我们需要查询前10个数字的和,那么我们只需要对31也就是前8个数的和加上5也就是9、10两个数字的和即可。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

{∞}

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值