[笔记-数据结构]树状数组

用于单点更新、区间查询
树状数组有两个操作:单点更新、区间查询
空间复杂度O(n),单点更新、区间查询时间均为log(n)


对于二维的区间来讲,我们可以使用二维树状数组

个人理解

蓝书翻到P196看图

  • 更新过程
    从11(1011)开始向上爬,作为右子树每次计算父节点(i-=lowbit(i))
    至于为何每次减少lowbit(i),是因为子树的白条长度正好为lowbit(i)
    11(1011) -> 10(1010) -> 8(1000) -> 0
  • 查询过程
    从3(0011)开始向上爬,作为左子树每次计算父节点(i+=lowbit(i))
    至于为何每次增加lowbit(i),是因为子树的白条长度正好为lowbit(i),而父节点白条长度正好为lowbit(i)×2
    3(0011) -> 4(0100) -> 8(1000) -> Max

模板

#define lowbit(x) ((x)&(-x))
int n, arr[int(5e4)+5];
long long getsum(int idx){
    long long sum=0;
    for (int i=idx; i>0; i-=lowbit(i))
        sum+=arr[i];
    return sum;
}

void add(int idx, int num){
    for (int i=idx; i<=n; i+=lowbit(i))
        arr[i]+=num;
}

注意

  1. 查询区间是[1, MAX]
    不是[0, MAX-1]啊,总是分不清。。。
    0是不可能算的,所有值的查找都包括了0,所以不能算啊
    所以说看了蓝书的图就没有问题了,0是一个类似终点的“节点”

例题

HDU-1166 敌兵布阵 树状数组
下面的题还不错
HDU-1541 Stars 树状数组

posted on 2018-02-23 15:45  糖栗子  阅读(117)  评论(0编辑  收藏  举报

导航