树状数组总结

来源:互联网 发布:mac安装flash插件 编辑:程序博客网 时间:2024/06/08 06:29

了解树状数组

树状数组这个数据结构是在设计压缩算法时被发现的。我觉得其中最重要的是运用了二进制的思想。(这个接下来会重点说)

树状数组的用途就是维护一个数组,重点不是这个数组,而是要维护的东西,最常用的求区间和问题,单点更新。但是某些大牛很6,完成部分线段树能完成的功能,比如区间更新,区间求最值问题。

树状数组是一个可以很高效的进行区间统计的数据结构。在思想上类似于线段树,比线段树节省空间,编程复杂度比线段树低,但适用范围比线段树小。树状数组和线段树很像,能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。

树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。 平常我们遇到的一些对数组进行维护查询的操作,比较常见的如,修改某点的值、求某个区间的和,而这两种恰恰是树状数组的强项!当然,数据规模不大的时候,对于修改某点的值是非常容易的,复杂度是O(1),但是对于求一个区间的和就要扫一遍了,复杂度是O(N),如果实时的对数组进行M次修改或求和,最坏的情况下复杂度是O(M*N),当规模增大后这是划不来的!而树状数组干同样的事复杂度却是O(M*log2N)。

二进制思想

这里写图片描述
树状数组的基础是一个被构造出来的式子:C[i]=A[i]+A[i-1]+….+A[i-2^k+1],k代表i的二进制的最后连续0的个数 比如 对于1000和101000,k=3。即C[i]=A[i]+…有lowbit(i)个A数组相加。lowbit(i)代表2^k即i最低位的1所代表的数。

接下来则很容易发现 节点和子节点的是有关系的,这种关系就是 i=j+lowbit(j);,lowbit是j的最低位1所代表的数字 比如对于 1000(8的二进制) 1000=100+lowbit(100)=110+lowbit(110)=111+lowbit(111)。这个关系是树状数组的核心,有了这个关系,我们可以把子区间的变化以log2n的次数传递上去。

接下来说一下求 1-n的和,举个例子 求1-11000 则 Sum(11000)=C[11000]+C[10000]。 因为 根据C[i]的构造方法 C[i]是从A[i]开始的2^k个元素的和,则C[11000]求了A[11000] +A[10111]+ A[10110]+ A[10101] +A[10100] +A[10010]+ A[10001] 这2^k个数 然后接着C[10000]求出了剩下 10000个元素的和 到了这我们就大概了解了树状数组的发明者的天才的构造是从何而来的了。普通的求1-n的和储存的数据太多,而这位天才则想,我们能不能根据二进制的思想来储存这些值呢?任何一个数,都可以由若干个二进制数相加而成,如果我们在求Sum(n)之前就知道了 n对应的二进制数从最低位开始,每个1所代表的数字的前2^i个数的和,我们不就能在时间复杂度log2n内求出所有的值 比如 101110 我们如果知道 101110->101101,101100->101001,101000->100001,100000->1各自的和,就可以在空间复杂度和时间复杂度很小的情况下求出1-101110了。然后对于区间和的修改,又利用每个小区间向上转移,修改了大区间的和。

代码部分

lowbit

int lowbit(int x) //求x的最低位1{    return x&(-x);  //这个自己体会下,了解点位于位运算的应该还是能明白。}

顺便说一下,用x&(-x)==x还能判断x是不是2^n数。

update

void update(int i,int value){    while(i<maxn)    {        c[i] += value;        i += lowbit(i);    }}

query

int query(int i){    int ans=0;    while(i>0)    {        ans += c[i];        i -= lowbit(i);    }    return ans;}

这里一定要注意:query函数的判断条件如果习惯写成while(x)的请注意一下,如果x为负数的话,会造成死循环。一定要将数据偏移到1下标开始,因为你是从1下标开始建的树状数组。

树状数组的基础基本就了解了,接下来你可以去尝试一些简单的树状数组题。我之后会写几篇树状数组的题解,感兴趣的看看树状数组的完整代码是怎样的。再过一段时间我还会写一下树状数组的专题。

1 0