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

Posted 你,好

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯备赛--带你入门树状数组相关的知识,希望对你有一定的参考价值。

概念

树状数组是用数据压缩的思想由二进制实现的数据结构。有单点修改+区间查询或区间修改+单点查询的作用。
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;

例题:

以上是关于蓝桥杯备赛--带你入门树状数组的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯备赛-常用数据结构vectorset和map

蓝桥杯备赛-常用数据结构vectorset和map

蓝桥杯备赛-常用数据结构vectorset和map

蓝桥杯备赛刷题

蓝桥杯备赛刷题

蓝桥杯备赛--二分查找