跳到主要内容

树状数组

参考资料

简介

树状数组(Binary Indexed Tree,BIT),又称 Fenwick 树,用 O(logn)O(\log n) 维护前缀信息并支持单点修改。借助 lowbit(x)=x&-x,节点 cxc_x 维护区间 (xlowbit(x),x](x-\operatorname{lowbit}(x),x] 的聚合值。修改时沿 xx+lowbit(x)x\to x+\operatorname{lowbit}(x) 上跳,查询前缀时沿 xxlowbit(x)x\to x-\operatorname{lowbit}(x) 下跳,单次操作 O(logn)O(\log n)。它实现简洁、常数小,适合维护前缀和、区间和等可差分的信息。

实现

146 Bcpp
struct BIT
{
int c[N];
void add(int u,int v){while(u<N){c[u]+=v;u+=u&-u;}}
int sum(int u){int res=0;while(u){res+=c[u];u-=u&-u;}return res;}
};

例题

如题,已知一个数列,你需要进行下面两种操作:

  • 将某一个数加上 xx
  • 求出某区间每一个数的和。

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数加上 xx
  2. 求出某一个数的值。

如题,已知一个数列 {ai}\{a_i\},你需要进行下面两种操作:

  1. 将某区间每一个数加上 kk
  2. 求出某区间每一个数的和。

维护一个二维矩阵,需要支持以下两种操作:

  • 将矩形区域内的所有数字增加 vv
  • 计算矩形区域内所有数字的总和。