从线段树的可删减性谈树状数组

这可能是我最后一次更新博客了呢

# 前言

很久之前,我初学树状数组的时候感觉非常的复杂、神奇、晦涩难懂。。。

果然还是我太菜了。后来了解到线段树的可删减性,这两者就自然而然的联系在一起了。

# 线段树的可删减性

很显然,对于一些区间操作的问题,线段树有着绝对的优势,基本上只要是区间查询之类的问题,那线段树是没跑了。

但是如果我们要查询的是前缀和这样的东西的话,会不会感觉线段树中的一些东西是多余的呢?

这么说可能有些不好理解,画画图就好:

上图如果看不清楚,请在新标签页中打开。(蓝色为节点标号,红色是区间端点)

假设我们查询到位置 9 的前缀和,那么答案就等于 2 号节点和 6 号节点的和。

这两个节点有什么奇怪的性质?

显然它们都是左孩子啊,那是不是所有的前缀和都是仅由左孩子节点构成的呢。

再试一下,就会发现,都是这样的。如何证明?

从根节点开始,答案有以下两种情况。

  • 在左孩子中。
  • 整个左孩子就是答案。
  • 整个左孩子加上右孩子的一部分。

先看第二种情况。。。那这根本没有悬念吧,只有左孩子。

那再看第一种情况,在左孩子中查找答案。那么答案还是分成上面的三种情况。

关键的就是来看第三种情况,那在右孩子中的答案就变成了 mid 到查询区间的右端点的和。

如果把左子树看做一个整体的话,只有变成了上面的差前缀和的问题。也就是说如果在右孩子中存在一部分答案的话,就会已知按照上面的三种情况划分下去,直到出现了第二种情况。

那第一种情况也是如此,已知分下去,问题要么直接变成第二种情况,要么先变成第三种情况再变成第二种情况。

而且观察我们的路径,会发现对答案有贡献的节点全部都是左端点。也就是说又断电时可以省略掉的。

如下图。

这就是线段树的可删减性。

# 再说树状数组

树状数组能解决的不正是前缀和的查询吗?那么我们再来看上面的图,删掉右孩子后,是不是变成了一个树状数组呢?

这就是两者之间的关系。

原文地址:https://www.cnblogs.com/bljfy/p/9926194.html

时间: 2024-10-02 07:29:51

从线段树的可删减性谈树状数组的相关文章

树状数组--前n项和;

树状数组是和线段树类似的数据结构,基本上树状数组可以做的线段树都可以做: 树状数组就是一个数组,在信息记录上有一些特点,以动态求前n项和为例:可以改变数组的某一个元素,求前n项和: 数组tree[ i ]记录的是A[ i - lowbit ( i )+1]~A[ i ]的和,lowbit(i),表示i的最低二进制是多少:表现在数组编号上就是上面的图中表现的东西: 求前n项和的操作: 1 #include<iostream> 2 #include<cstdio> 3 using na

树状数组详解

一.引入和概念 平常我们会遇到一些对数组进行维护查询的操作,比较常见的,修改某点的值.求某个区间的和. 数据规模不大的时候,对于修改某点的值是非常容易的,复杂度是O(1),但是对于求一个区间的和就要扫一遍了,复杂度是O(N). 如果实时的对数组进行M次修改或求和,最坏的情况下复杂度是O(M*N),当规模增大后这是划不来的. 而树状数组干同样的事复杂度却是O(M*lgN). 树状数组是一个查询和修改复杂度都为log(n)的数据结构. 主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素

浅谈二维中的树状数组与线段树

一般来说,树状数组可以实现的东西线段树均可胜任,实际应用中也是如此.但是在二维中,线段树的操作变得太过复杂,更新子矩阵时第一维的lazy标记更是麻烦到不行. 但是树状数组在某些询问中又无法胜任,如最值等不符合区间减法的询问.此时就需要根据线段树与树状数组的优缺点来选择了. 做一下基本操作的对比,如下图. 因为线段树为自上向下更新,从而可以使用lazy标记使得矩阵的更新变的高校起来,几个不足就是代码长,代码长和代码长. 对于将将矩阵内元素变为某个值,因为树状数组自下向上更新,且要满足区间加法等限制

【BZOJ4785】[Zjoi2017]树状数组 树套树(二维线段树)

[BZOJ4785][Zjoi2017]树状数组 Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进行 m 次操作,操作有两种: 1 x,表示将 Ax 变成 (Ax + 1) mod 2. 2 l r,表示询问 sigma(Ai) mod 2,L<=i<=r 尽管那个时候的可怜非常的 simple,但是她还是发现这题可以用树状数组做.当时非常yo

线段树与树状数组草稿

http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=604&pid=1002 Dylans loves sequence Accepts: 249 Submissions: 806 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description Dylans is given N

POJ 2481 树状数组 区间覆盖(POJ2352 Stars 的变形题)(线段化点)

0)学会将题目情景转化为自己熟悉的结构或模型. 题目大意: 每个奶牛有自己的一个区间,求每个奶牛的区间所覆盖的子区间个数(注意,真子集,相等的不算),按照输入的顺序输出. 转化: 要学会将题目情景转化为自己熟悉的模型或结构上.把每个区间的左端x值作为点的x坐标,右端x值作为点的y坐标,就可以把所有区间转化为一个二维坐标图上的点集,而此时每个点左上方的点(同Stars那道题目一样不包括自身)的个数,就是每个区间所覆盖的子区间的个数(对应题目要求,这里或许可以再变形). 同POJ2481 Stars

Vijos P1066 弱弱的战壕【多解,线段树,暴力,树状数组】

弱弱的战壕 描述 永恒和mx正在玩一个即时战略游戏,名字嘛~~~~~~恕本人记性不好,忘了-_-b. mx在他的基地附近建立了n个战壕,每个战壕都是一个独立的作战单位,射程可以达到无限(“mx不赢定了?!?”永恒[email protected][email protected]). 但是,战壕有一个弱点,就是只能攻击它的左下方,说白了就是横纵坐标都不大于它的点(mx:“我的战壕为什么这么菜”ToT).这样,永恒就可以从别的地方进攻摧毁战壕,从而消灭mx的部队. 战壕都有一个保护范围,同它的攻击

Curious Robin Hood(树状数组+线段树)

1112 - Curious Robin Hood    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 MB Robin Hood likes to loot rich people since he helps the poor people with this money. Instead of keeping all the money together he does another tri

[luogu P3801] 红色的幻想乡 [线段树][树状数组]

题目背景 蕾米莉亚的红雾异变失败后,很不甘心. 题目描述 经过上次失败后,蕾米莉亚决定再次发动红雾异变,但为了防止被灵梦退治,她决定将红雾以奇怪的阵势释放. 我们将幻想乡看做是一个n*m的方格地区,一开始没有任何一个地区被红雾遮盖.蕾米莉亚每次站在某一个地区上,向东南西北四个方向各发出一条无限长的红雾,可以影响到整行/整列,但不会影响到她所站的那个地区.如果两阵红雾碰撞,则会因为密度过大而沉降消失.灵梦察觉到了这次异变,决定去解决它.但在解决之前,灵梦想要了解一片范围红雾的密度.可以简述为两种操