树状数组模板

95 阅读1分钟

树状数组概念

树状数组的目的

树状数组是用了求动态前缀和的数据结构

时间复杂度修改和查询时间代价都是O(logn),其中 n为需要维护前缀和的序列的长度。

如何理解呢?比如我们拿[5,5,2,3,6]来举例,我们需要求满足1<=i<j<=lennum[i]<num[j](i,j)个数

此时我们已数组的值为创建Tree的依据

index -> 1 2 3 4 5 6 7 8 9 
value -> 0 1 1 0 2 1 0 0 0

Snipaste_2022-10-02_22-33-31.png

我们至于要对Tree进行操作就能得到相应的结构且Tree的大小从1开始

  • 第一种Tree,以值作为Tree数组的长度
  • 第二种,离散化,以长度作为Tree的长度

lowbit函数其实是一个将数组划分的依据,如上图所示,设我们1-3区间的前缀,既求querty(3) 3-lowbit(3)=2;此时querty(3)=tree[3]+tree[2]

树状数组模板

数组从1开始
int lowbit(x){
    return x&(-x);
}
int querty(int x){//查询区间1-x的前缀和
    int res=0;
    while(x){
        res+=tree[x];
        x-=lowbit(x);
    }
    return res;
}
void update(int x){//更新x的前缀,并更新受x影响的前缀
    while(x){
        tree[x]++;
        x+=lowbit(x);
    }
}