树状数组简单总结

来源:互联网 发布:js 对象访问器 编辑:程序博客网 时间:2024/06/07 03:02
1、树状数组最早用于数据压缩。
2、c[i]的初始位置是去掉最低位的1之后加上1.(最后一个1代表的权值表示c中拥有a的个数。)
3、c[i]下标的起点是下标 x=i-[i&(-i)]+1;
4、树状数组之所以高效简洁的原因就是能够利用位运算直接求出i对应的lowbit。
# define lowbit(x)((x)&(-x));int lowbit(int i){return i&(-i);}


5、某一a[i]的值,位于数状数组中位置关系是i=i+lowbit(i)
void update(int i,int data){while(i<=n){c[i]+=data;     //改变需要修改的数据。i+=lowbit(i);  //a[i]所在的下一个c中的位置。}}


6、树状数组与原始数组的关系:
c[i]=a[i-lowbit(i)+1]+...a[i];
以及
a[i]∈c[i],c[i=i+lowbit(i)],c[i=i+lowbit(i)]...
7、树状数组与累加数组:
sum[i]=c[i]+c[i=i-lowbit(i)]+c[i=i-lowbit(i)]+...;(最后一个1代表的权值与i位置的差即为sum包含的数的个数0的时候是1)
int query(int i){    int ans=0;     while(i>0){    ans+=c[i];    i-=lowbit(i);    }return ans;}


8、扩展到多维时的情形:
void update(int x,int y,int data){for(;x<=n;x+=lowbit(x))    for(j=y;j<=m;j+=lowbit(j))    c[x][j]+=data;}/*updata数据插入*/int query(int x,int y){    int ans=0;    for(;x>0;x-=lowbit(x))       for(j=y;j>0;j-=lowbit(j))           ans+=c[x][j];return ans;}

/*query求和查询*/
9、树状素组特点:
(1)树状数组十分容易进行编程实现。
(2)树状数组的每个操作花费常数时间或是o(log2N)的时间。
(3)树状数组需要线性的存储空间o(n),只维护c数组。
(4)树状数组可以扩展为n维的情况。
10、总结:
弊端:
(1)树状数组的致命缺点是无法记录一些附加信息,比如:不相交区间的个数,就无法用树状数组维护
(2)树状数组的应用范围是很窄的。(求和的问题可以用树状数组,如果求最大值操作,而且没有删除操作的话,那么也能够用树状数组。)






原创粉丝点击