树状数组(单点更新-区间查询,区间更新-单点查询,区间更新-区间查询,二维树状数组)

树状数组(单点更新-区间查询,区间更新-单点查询,区间更新-区间查询)

树状数组和线段树的比较:

1.都用来求区间问题,优化时间复杂度。它和线段树有着相似的功能,都能求,单点更新-区间查询,区间更新-单点查询,区间更新-区间查询 这些问题。

2.二者有着相似的时间复杂度。log()级的查询与修改。

3.树状数组的功能,用线段树完全能够实现,但是由线段树能实现的功能树状数组不一定能够实现。 线段树>树状数组。

4.既然功能不如线段树多,那为什么还要学树状数组呢?因为树状数组变成简单啊。代码少,写起来快啊~~。

树状数组的原理:

树状数组,顾名思义就是树状的数组。如图,就是一个变形的完全二叉树。
在这里插入图片描述
我们给每个块块都标上数值如下:
在这里插入图片描述
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]
这样我们更新A数组的时候 只需要更新与A相关的C数组就好,比如你要更新 A[1] 只需要更新与A[1] X相关的 C[1] C[2] C[4] C[8] 就好。
那么问题来了,我们这个C数组是怎么分的呢??转换给2进制就很明了了
C[1] = C[0001] = A[1];

    C[2] = C[0010] = A[1]+A[2];

    C[3] = C[0011] = A[3];

    C[4] = C[0100] = A[1]+A[2]+A[3]+A[4];

    C[5] = C[0101] = A[5];

    C[6] = C[0110] = A[5]+A[6];

    C[7] = C[0111] = A[7];

    C[8] = C[1000] = A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

C数组管辖的A的个数 = 2^k(个) k等于啥呢。 k就是这个二进制的从后往前连续0的个数,比如C[8] = C[1000] 后面连续三个0 所以k 就等于3 再比如C[6] =C[0110] 从后往前连续的0只有1个就断了 所以k=1.

那么 问题又来了,虽然我们明白了原理,知道了C 数组 怎么来的,我们怎么实现呢??
这里引入一个 lowbit(x) 函数,函数的功能就是取 x的最低位的1.代码很短。但是树状数组全靠它。

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

取最后位的1 啥用呢?你想啊,我们每次更新的时候,要找相关的C 我们只要每次加一下lowbit不就好了嘛~
比如更新A[1] ,我们要更新的C分别得C[1] C[2] C[4] C[8]
1+lowbit(1) . 1的最低位的1还是1 所以1+lowbit(1) =2
2+lowbit(2) . 2=10 最低位的1 代表2 所以 2+lowbit(2) = 2+2 = 4;
4+lowbit(4) . 4=100 最低位的1 代表4 所以 4+lowbit(4)= 4+4= 8
同样,查询的时候我们只要往前查询就行了。每次减 lowbit()

单点更新,区间查询。

**更新操作:**正如我们前面所说的,更新的时候,只需要更新与它相关联的C数组就好,所以我们往上找,每次加lowbit()

void update(int x,int val)
{
   
	for(int i=x;i<=n;i+=lobwit(i)){
   
		c[i]+=val;
	}
}

查询操作:,查询应该查询往下找,每次减lowbit()
需要注意的是!! 我们 这样得到的结果是 A[1]+A[2]+…+A[N];

int query(int x)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值