关于树状数组

Posted intmian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于树状数组相关的知识,希望对你有一定的参考价值。

技术图片

lowbit是什么?

  • lowbit(i)=i&-i
  • 对应于末尾的1所在位置的一个数
  • 节点高度/对应区间长度

i的父节点为lowbit(i)+i

  • 可以观察到它的兄弟节点即是它的父节点
  • 最少加上lowbit(i)后lowbit才会增加,即lowbit(i)+i为离i最近的上一层节点

点修改

区间和

void add(int no,int num){
    for(int i=no;i<=n;i+=i&-i)
        c[i]+=num;
}

区间最值

  1. 更新所有父节点
  2. 在每个节点中,采用倍增的思想:
max[12]=max(a[12],c[12-1],c[12-2])
c[12] a[12] c[12-1] c[12-2]
lowbit 4 1(元素本身) 1 2
void update(int no,int num){   
  c[no]=a[no]=num;
  for(int i=1;i<(no&-no);i<<=1)
    c[no]=max(c[no],c[no-i]);
}

区间询问

区间和(前缀和)

倍增:sum[5]=c[4]+c[5];

int ask(int no){
  int out=0;
  for(int i=no;i;i-=i&-i)
    out+=c[i];
  return out;
}

区间最值

3=(11)2
11=(1011)2

max(3,11)=max(a[11],c[10],a[8],c[7],c[5],a[4],c[3])
a[11] a[10] a[8] a[7] a[5] a[4] a[3]
lowbit 1 2 / 1 2 / 1
之后 1010 1000 111 110 100 11
之前 1011 1010 1000 111 110 100 11
int ask(int l,int r){
  int ans=0;
  while(r>=l)
  {
    ans=max(ans,a[r]);
    r--;
    for(;r-(r&-r)>=l;r-=r&-r)
      ans=max(ans,h[r]);
  }
  return ans;
}

以上是关于关于树状数组的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之树状数组从零认识树状数组

关于树状数组

几个关于js数组方法reduce的经典片段

关于树状数组套主席树的一些博客

关于二进制&异或&树状数组的问题研究

关于二进制&异或&树状数组的问题研究