树状数组(入门附模板)

本文介绍了树状数组(Fenwick树)的基础知识,包括其用于解决累积频率计算的问题,以及在单点修改和区间查询上的应用。文章通过对比树状数组与线段树的区别,讲解了lowbit函数、结构分析,并提供了单点修改和区间查询的代码模板,以及区间修改和单点查询的操作。此外,还讨论了树状数组在区间修改和区间查询中的使用,最后给出了相关编程挑战的示例。
摘要由CSDN通过智能技术生成

声明:本篇文章图片非原创 

目录

简介

lowbit函数

结构分析

单点修改,区间查询

区间修改,单点查询

区间修改,区间查询

模板题

树状数组1–单点修改,区间查询

题目描述

输入格式 

输出格式

输入输出样例

输入 #1

输出 #1

说明/提示

分析

代码

树状数组2––区间修改,单点查询

题目描述

输入格式

输出格式

输入输出样例

输入 #1

输出 #1

说明/提示

样例 1 解释:

数据规模与约定

分析

代码

最强编译器推荐


简介

        树状数组二叉索引树(英语:Binary Indexed Tree),又以其发明者命名为Fenwick树,最早由Peter M. Fenwick于1994年以A New Data Structure for Cumulative Frequency Tables为题发表在SOFTWARE PRACTICE AND EXPERIENCE。其初衷是解决数据压缩里的累积频率(Cumulative Frequency)的计算问题,现多用于高效计算数列的前缀和, 区间和。        ——源自百度百科

        百度百科太过于学术化,看不懂?怎么办?总的来说,树状数组是一种支持单点修改区间查询的一种代码量小的数据结构。

        那么树状数组和线段树有什么区别呢?

  1. 线段树的码量很明显比树状数组多
  2. 线段树可以进行区间修改和区间查询,然而树状数组是线段树的低级版本,可以进行区间查询,但只能一次性改一个点,当然,经过改造后的树状数组可以进行区间修改,我们今天先讲树状数组的低级版本。

如上图,这就是树状数组的形式,仔细看一看,你会发现树状数组是不规则的叉树。下图是线段树的样子

两者还是有很多地方是不一样的。

lowbit函数

要想学会树状数组,我们必须要理解一个函数:lowbit()

lowbit()就是求一个数与上他的相反数,简单来说,就是x&(-x)

想要算lowbit(x)很简单,举个栗子:

假设一个数 x=5,5的二进制编码为0101。根据我们的二进制原理,则-x也就是1011,所以x&(-x)=1,如果你再举几个例子,细心地你就会发现,x的二进制编码的第一个1的位置就是lowbit(x)的值?

下面给出lowbit的函数模板

//version 1 
int lowbit(int x){
	return x&(-x);
}
//version 2
#define lowbit(x) x&(-x) 

结构分析

先放一张图片

        看了这一张图片,我们会发现,每一层的下表的二进制编码末尾的0的个数都是相同的,而且是从下至上一次递增的。

        那么原数组前4项的和t[4]=t[2]+t[3]+a[4]=t[1]+a[2]+t[3]+a[4]=a[1]+a[2]+a[3]+a[4]

        看了这一张图片之后,你是不是发现了更多的奥秘了呢? 树状数组中节点x的父节点为x+lowbit(x),例如t[2]的父节点为t[4]=t[2+lowbit(2)].

当你理解了这些之后,就可以尝试一下编写代码了.

单点修改,区间查询

        我们消化了上面的内容之后,会发现,编写树状数组的代码会变得尤为简单.在这里,我们先来看一下如何在树状数组里进行单点修改,区间查询.

        如果我们将a数组进行+k操作,那么它的父亲节点都要加上一个k. 举个栗子:如果我们要将a[1]数组进行+k操作,那么如上图t[1],t[2],t[4],t[8]都要加上一个k(因为我们是用差分建的数,所以更改单点的值时也要牵扯到它的祖宗).

        此时,我们就要运用到我们前面学的lowbit函数了!下面是单点修改的代码

int one_change(int x,int k){
	for(int i=x;i<=n;i+=lowb
  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cqbzcyy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值