蓝桥杯备赛--带你入门树状数组
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;
例题:
以上是关于蓝桥杯备赛--带你入门树状数组的主要内容,如果未能解决你的问题,请参考以下文章