A-1:树状数组

ops/2024/9/24 8:47:15/

A-1:树状数组

  • 1.介绍
    • Q1:树状数组解决什么问题?
    • Q2:树状数组的使用
      • 1.前置知识:lowbit(x)
      • 2.单点修改
      • 3.求[1,n]的和
      • 4.区间查询
      • 5.hh
    • Q3:树状数组是否优化了
    • Q4:上图上例子解释上面说的东西(Important)
  • 2.习题练习

1.介绍

树状数组是一个比较难以理解的高级数据结构(至少我觉得很难😢)

由于难以理解,所以只好从以下几个方面去理解:

  1. 树状数组用于解决什么问题
  2. 如何去使用树状数组
  3. 树状数组是否优化算法
  4. 用例子说明

新手不要去死钻“树状数组怎么被总结出来的?树状数组的发明过程”,如果有完美的回答感谢给个链接我去圆梦一下😢

!!对于这个学习,我的看法是先知道什么是树状数组,怎么写,然后根据数据和画图走几遍过程,然后做题。最后再去看数学推导(如果时间充裕的话)。

Q1:树状数组解决什么问题?

预告:数状数组解决”单点修改,区间查询(当然区间也可以是一个点)“问题

首先前缀和是大家都知道的基础算法。假设前缀和数组是 p r e [ n ] pre[n] pre[n],原数组是 a [ n ] a[n] a[n]
p r e [ i ] 表示数组区间 [ 0 , i ] 之和 = a [ 0 ] + a [ 1 ] + a [ 2 ] + . . . + a [ i ] pre[i]表示数组区间[0,i]之和=a[0]+a[1]+a[2]+...+a[i] pre[i]表示数组区间[0,i]之和=a[0]+a[1]+a[2]+...+a[i]
查询区间的时间复杂度是 O ( 1 ) O(1) O(1),比如: 查询 [ i , j ] [i,j] [i,j]之和= p r e [ j ] − p r e [ i − 1 ] = a [ i ] + a [ i + 1 ] + . . . + a [ j ] pre[j]-pre[i-1]=a[i]+a[i+1]+...+a[j] pre[j]pre[i1]=a[i]+a[i+1]+...+a[j],很显然只需要一次操作即可。
重点来了!! 如果修改原数组的一个元素,假设 a [ 0 ] = a [ 0 ] + 1 a[0]=a[0]+1 a[0]=a[0]+1,那么需要 p r e [ 0 ] + 1 pre[0]+1 pre[0]+1 p r e [ 1 ] + 1 pre[1]+1 pre[1]+1 p r e [ n ] + 1 pre[n]+1 pre[n]+1
总结发现,每次修改一个原数组元素,当前元素到数组末尾的所有元素的前缀和都需要改变,那么维护前缀和的时间复杂度是 O ( n ) O(n) O(n),树状数组就是优化掉这个O(n)的大杀器!

总结一下:数状数组解决”单点修改,区间查询(当然区间也可以是一个点)“问题

Q2:树状数组的使用

😱😱😱😱😱

1.前置知识:lowbit(x)

l o w b i t ( x ) lowbit(x) lowbit(x),找x最低位的1及1右边(比1更低位)的所有数的总和,当然最低位1右边全是0

x的十进制数x的二进制数lowbit(x)(换成十进制)
1010102
1110111
1211004
1311011
1411102
1511111
160001 000016

现在应该是了解lowbit做一个什么事情,那么如何实现呢?

void lowbit(x)
{return x&(-x);
}

对的,就是这么简单
对数取负表现为 ”除最高位,其余位取反,最低位加1”
来翻译一下: 令x=10
x=1010
-x=1110
x&(-x)=0010

Perfect😋。

2.单点修改

不同于前缀和数组,修改一个点,需要修改O(n)次前缀和区间,而树状数组只需要修改O( log ⁡ 2 n \log_2 n log2n)次
操作为

void add(int i, int y)  //单点修改(同时可以初始化C数组)
{for(;i<=n;i+=lowbit(i)){C[i]+=y;}
}

3.求[1,n]的和

不同于前缀和O(1)次,查询前n个数的和需要O( log ⁡ 2 n \log_2 n log2n)次
操作为

int sum(int i)  //前缀和,求[1,i]的和
{int res=0;for(;i>0;i-=lowbit(i))res+=C[i];return res;
}

4.区间查询

操作为

int Query(int i,int j)  //查询[1,j]区间和
{return sum(i)-sum(j-1);
}

5.hh

很显然,已经给出了单点修改,区间查询的操作,且时间复杂度实实在在更低更有效,比单纯使用前缀和好很多。那么有这些知识就可以去写题了。

Q3:树状数组是否优化了

和前缀和相比:

前缀和树状数组
区间查询O(1)O( log ⁡ 2 n \log_2 n log2n)
单点修改O(n)O( log ⁡ 2 n \log_2 n log2n)

当n非常大的时候
1 + n > 2 ∗ ( log ⁡ 2 n ) 1+n>2 *(\log_2 n) 1+n>2(log2n)

Q4:上图上例子解释上面说的东西(Important)

在这里插入图片描述
这个图是 借的,嗯,肯定是借的。
别被误导了!!,C数组不是前缀和,C[4]不是前4个数之和,这个数组单独看没有意义,只有和函数配合使用才有意义!!

现在先抛出问题:需要对数组进行单点修改,区间查询。

现在有数组 A [ 1 ] . . . A [ 8 ] = 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 A[1]... A[8]={1,2,3,4,5,6,7,8} A[1]...A[8]=1,2,3,4,5,6,7,8
先初始化树状数组C,这个数组单独不代表什么,要和其它操作一起才有意义

void add(int i, int y)  //单点修改(同时可以初始化C数组)
{for(;i<=n;i+=lowbit(i)){C[i]+=y;}
}
C[i]+=yi+=lowbit(i),C[i]+=yi+=lowbit(i) ,C[i]+=yi+=lowbit(i),C[i]+=y
C[1]+=1C[2]+=1C[4]+=1C[8]+=1
C[2]+=2C[4]+=2C[8]+=2
C[3]+=3C[4]+=3C[8]+=3
C[4]+=4C[8]+=4
C[5]+=5C[6]+=5C[8]+=5
C[6]+=6C[8]+=6
C[7]+=7C[8]+=7
C[8]+=8
iC[i]
11
23
33
410
55
611
77
836

这就是初始化树状数组,那么先来看查询。
查询 (对照上面的表看,自己琢磨一下)

int sum(int i)  //前缀和,求[1,i]的和
{int res=0;for(;i>0;i-=lowbit(i))res+=C[i];return res;
}
isum(i)
1res=C[1]=1
2res=C[2]=3
3res=C[3]+C[2]=6
7res=C[7]+C[6]+C[4]=28
8res=C[8]=36

2.习题练习

给个链接,兄弟们去刷吧😋
洛谷树状数组题集
Leetcode树状数组题集

洛谷的先做题集里面的模板题

稍后把我的题解搬几个过来。


http://www.ppmy.cn/ops/4763.html

相关文章

WPF App.xaml 中添加多个ResourceDictionary

在WPF应用程序中&#xff0c;App.xaml 文件是一个常用的集中位置来管理应用级别的资源&#xff0c;包括样式、模板、图像、数据转换器等。为了添加多个 ResourceDictionary 到 App.xaml 中&#xff0c;可以利用 ResourceDictionary 的 MergedDictionaries 属性。这个属性允许您…

2024npm国内镜像源

npm 官方原始镜像网址是&#xff1a;https://registry.npmjs.org/ 淘宝 NPM 镜像&#xff1a;https://registry.npmmirror.com 阿里云 NPM 镜像&#xff1a;https://npm.aliyun.com 腾讯云 NPM 镜像&#xff1a;https://mirrors.cloud.tencent.com/npm/ 华为云 NPM 镜像&#x…

【切换网络连接后】VMware虚拟机网络配置【局域网通信】

初次安装Linux虚拟机以及切换网络都需要配置虚拟机网络&#xff0c; 从而使得win主机内通过远程连接工具能够连接该虚拟机&#xff0c; 而不是在虚拟机内操作。 本片文章你将了解到网络切换后如何配置虚拟机网络的一些基础操作&#xff0c;以及局域网通信的一些基础知识。 …

链表经典算法OJ题目

1.单链表相关经典算OJ题目1&#xff1a;移除链表元素 思路一 直接在原链表里删除val元素&#xff0c;然后让val前一个结点和后一个节点连接起来。 这时我们就需要3个指针来遍历链表&#xff1a; pcur —— 判断节点的val值是否于给定删除的val值相等 prev ——保存pcur的前…

深入理解汇编:平栈、CALL和RET指令详解

​视频学习下载地址&#xff1a;​​https://pan.quark.cn/s/04e6946a803a​​ 汇编语言以其接近硬件的特性和高效的执行速度&#xff0c;在系统编程、性能优化和逆向工程中占有不可或缺的地位。本文将深入探讨汇编语言中的平栈操作以及​​CALL​​​和​​RET​​指令&#…

聚观早报 | 华为Pura70系列先锋计划;月之暗面升级Kimi

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月19日消息 华为Pura70系列先锋计划 月之暗面升级Kimi OPPO Find X7将推白色版本 波士顿动力推出人形机器人 v…

vue flvjs 播放视频

写在前面&#xff1a; 之前使用过vodiejs插件播放过mp4视频格式的视频&#xff1b; 此次需要使用flvjs插件播放rtsp视频格式的视频&#xff1b; 因为视频的数据格式不同&#xff0c;所以对应的插件不同。 思维导图&#xff1a; 参考链接&#xff1a;rtmp、rtsp、flv、m3u8、 …

Windows版Apache 2.4.59解压直用(免安装-绿色-项目打包直接使用)

windows下Apache分类 Apache分为 安装版和解压版 安装版: 安装方便&#xff0c;下一步------下一步就OK了&#xff0c;但重装系统更换环境又要重新来一遍&#xff0c;会特别麻烦 解压版&#xff08;推荐&#xff09;&#xff1a; 这种方式&#xff08;项目打包特别方便&#x…