【基础算法-树状数组】入门-C++

@

基本定义

树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。

如何理解树状数组

树状数组,重点在于它是树状(这不废话吗)
大家都知道二叉树吧,贴一张二叉树的图给大家理解一下(自己画的有点丑)
在这里插入图片描述
我们把它变形一下...

在这里插入图片描述
现在定义每一列的顶端结点C[]数组
在这里插入图片描述
ps.最后一个图不是我画的

C[i]代表子树的叶子结点的权值之和, 这里以求和举例

如图可以知道

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[]数组的结点序号转化为二进制

1=(001) C[1]=A[1];

2=(010) C[2]=A[1]+A[2];

3=(011) C[3]=A[3];

4=(100) C[4]=A[1]+A[2]+A[3]+A[4];

5=(101) C[5]=A[5];

6=(110) C[6]=A[5]+A[6];

7=(111) C[7]=A[7];

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

对照式子可以发现 C[i]=A[i-2^ k+1]+A[i-2^k+2]+......A[i];
(k为i的二进制中从最低位到高位连续零的长度)例如i=8时,k=3;

可以自行带入验证;

现在引入lowbit(x)

lowbit(x) 其实就是取出x的最低位1 换言之 lowbit(x)=2^k k的含义与上面相同 理解一下

主要操作

添加元素
单点修改
单点查询
区间修改
区间查询

前两个普通数组能够O(1)时间复杂度完成,后两个普通数组需要O(n)时间复杂度完成,而树状数组最大只需要O(logn),这也正是树状数组的快捷之处。

代码实现

0.lowbit操作

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

不懂的看下上面引用的那一段
1.添加元素

void add(int s,int num)
{
	for(long long i=s;i<=n;i+=lowbit(i))
		tree[i]+=num;
	return;
}

添加元素的操作可能有些不好理解,但同上,只要理解了lowbit操作,基本就能看懂这个添加操作了...
2.单点修改
这个操作普通数组只要O(1)的时间复杂度,但是树状数组需要最高 O(logn)的时间,因为在树状数组中数组中的一些元素是有联系的,修改其中一个就需要牵扯到很多...

void add(int x,int k)
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=lowbit(x);
    }
}

3.单点查询
依然,普通数组O(1),树状数组最高O(logn)

long long ask(long long s)
{
    long long ans=0;
    for(long long i=s;i>=1;i-=lowbit(i))
		ans+=tree[i];
    return ans;
}

4.区间修改
这个操作就是树状数组的强项之一了,普通数组O(n),树状数组也是不到O(logn)跑出来

void add(int s,int num)
{
	for(long long i=s;i<=n;i+=lowbit(i))
		tree[i]+=num;
}

p.s.把[x,y]区间的数加上s,需要add(x,s);add(y+1,-s);
5.区间查询
这依然是树状数组的强项,时间复杂度同4

int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}

树状数组模板题:
只需要树状数组基本知识
需要用到差分
ov.

posted @ 2019-07-19 20:32  摸鱼酱  阅读(1564)  评论(0编辑  收藏  举报