数据结构————树状数组

原数组--->前缀和------>范围和

原数组更改数组元素在求和效率较低,引入树状数组

假设原数组A【】 树状数组C【】

树状数组 的三种操作:

1.lowbit() 子叶数(二进制最低位的1代表多少)

数据结构————树状数组

 

代码实现:

 int lowbit(int n)
{
   return x&(-x);
}

 

 

求:lowbit(x) returnx&(-x)

2.

update()// A[i]+k       假设A【i】是原数组C[i]为树状数组,改变A【i】个更新C[i]

   update(i,k) ;

  c[i]=c[i]+k;//首先更新从c【i】本身,然后更新它的父节点

   i=i+lowbit(i);//更新c[i]的父节点
   i<=n;//下一步 循环update()更新所有的父节点,直到满足截止条件i<=n

代码实现:

/*树状数组支持单点操作,对某个数A【x】加上y,同时正确维护序列的前缀和*/
void update(int x,int y)
{
   for(;x<=N;x+=x&-x)
     c[x]+y;
}

3.sum()利用树状数组求原数组的前缀和

sum(i);//表示从A【1】一直加到A[i]
ans=c[i]+ans;
i=i-lowbit(i);//循环
i>0;//循环截止的条件

如:求区间【l~r】的和

sum(k)-sum(l-1);

代码实现:

树状数组支持查询前缀和,即序列A~x个数的和

int sum(int x)
{
  int ans;
  for(;x-=x&-x) ans-=c[x];
  return ans;
}