树状数组

树状数组是实现单点修改,前缀查询的数据结构。

图中的c数组就是树状数组,可以看出一个c数组对应了不同数量的原始数组(a数组)的值。

为了实现这种存储结构,有必要引出lowbit这个概念。

 

首先,lowbit(x) = x & -x。

是什么原理,我觉得我将不太明白,各位百度一下吧,网上有很多不错的解释。

用法,举个栗子。lowbit(6) = 2,lowbit(6 - 2) = lowbit(4) = 4,lowbit(4 - 4) = lowbit(0) = 0。

这代表了什么含义呢?就是如果一个数x一直减去它的lowbit的话,就能遍历x之前树状数组存的所有值。

这样查询前缀和的代码就可以写出来了

 1 int sum(int pos)
 2 {
 3     int ret = 0;
 4     while(pos > 0)
 5     {
 6         ret += c[pos];
 7         pos -= lowbit(pos);
 8     }
 9     return ret;
10 }

 

那单点修改呢?其实只要一直加上lowbit就行。

1 void add(int pos, int w)
2 {
3     while(pos <= n)
4     {
5         c[pos] += w;
6         pos += lowbit(pos);
7     }
8 }

这就是树状数组的板子了。

 

啊,补一个lowbit

1 int lowbit(int x)
2 {
3     return x & -x;
4 }

 

posted @ 2018-03-17 21:50  mrclr  阅读(152)  评论(0编辑  收藏  举报