蓝桥杯备赛--带你入门树状数组

树状数组是一种用于高效单点修改和区间查询的数据结构,常用于大数据量的求和操作,时间复杂度为O(logn)。通过lowbit()函数确定更新路径,add()函数用于构建树状数组,getSum()函数用于区间求和。博客详细解释了树状数组的构建过程及应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念

树状数组是用数据压缩的思想由二进制实现的数据结构。有单点修改+区间查询或区间修改+单点查询的作用。
A[]为一维数组,C[]为树状数组
在这里插入图片描述
由图可知:

	C[1] = A[1]
	C[2] = A[1]+A[2]
	C[3] = A[3]
	C[4] = A[1]+A[2]+A[3]+A[4]
	C[5] = A[5]
	C[6] = A[5]+A[6]
	C[7] = A[7]
	C[8] = A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8]
	C[N] = A[N-2^K+1] + A[N-2^K+2] + ····· + A[N]   (K为N的二进制数的最低1前0的个数,如1000,则K为3)

可以明显看出,在数据量大时,树状数组求和更快,对于长度为n的数组,求和的时间复杂度为o(logn)。
那么如何构建树状数组呢?下面就需要引入lowbit()函数。
lowbit()函数求得下一步要去哪里

// x 为数组下标
int lowbit(int x) {
	return x & -x;
}

lowbit()函数实际上就是求最低位1的位置,如x = 110,-x = 010, 再求与得 010,说明最低位在第2位,K = 2,即下一层是在第二层,就可以开始一层一层构建树状数组了!

下面引入add()函数来构建树状数组。

// x为插入值,y为当前索引号,n为数组长度
void add(int x, int y, int n){
	for (int i = y; i <= n; i += lowbit(i)) c[i] += x;
}

看不懂没关系,我们来举个例子演示一下。
比如现在要在长度为4的数组的第一位中插入1,即add(1,1,4)
在这里插入图片描述

再向长度为4的数组的第二位插入1,即add(1,2,4)。
在这里插入图片描述
再向长度为4的数组的第三位插入1,即add(1,3,4)。
在这里插入图片描述
这样大概明白了吧。
而求和与add()函数类似,只是方向相反。

// 求 1 ~ x 的和
int getSum(int x){
	int ans = 0;
	for (int i = x; i; i -= lowbit(i)) ans += c[i];
	return ans;
}

例题:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值