码迷,mamicode.com
首页 > 编程语言 > 详细

关于树状数组

时间:2019-03-24 13:34:42      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:alt   长度   for   技术   它的   关于   mamicode   思想   增加   

技术图片

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;
}

关于树状数组

标签:alt   长度   for   技术   它的   关于   mamicode   思想   增加   

原文地址:https://www.cnblogs.com/intmian/p/BIT.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!