树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值。这种数据结构(算法)并没有C++和Java的库支持,需要自己手动实现。在Competitive Programming的竞赛中被广泛的使用。树状数组和线段树很像,但能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。
int lowbit(int x) //取x的最低位1,比如4,则返回4,如5,则返回1
{
return x&(-x);
}
void update(int i, int val) //将第i个元素增加val
{
//i的祖先都要增加val
while(i <= n)
{
sum[i] += val;
i += lowbit(i); //将i的二进制未位补为得到其祖先
}
}
int Sum(int i) //求前i项的和
{
int s = 0;
//将前i项分段
while(i > 0)
{
s += sum[i];
i -= lowbit(i); //去掉i的二进制最后一个
}
return s;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int y, int val) //将 a[x][y] 的值增加val
{
for(int i=x; i<N; i+=lowbit(i))
{
for(int j=y; j<N; j+=lowbit(j))
{
sum[i][j] += val;
}
}
}
//二维树状数组
int getSum(int x, int y) //求以1,1为左上角端点,学校,x,y为右下角端点的矩阵和.
{
int s = 0;
for(int i=x; i>0; i-=lowbit(i))
{
for(int j=y; j>0; j-=lowbit(j))
{
s += sum[i][j];
}
}
return s;
}