与线段树相似,但是没有线段树扩展性好
树状数组的优点是实现较快
lowbit函数:表示二进制数最后一个1即后续0组成的数字(lowbit 101100 = 100)
int lowbit(int x)
{
return x&(-x);
}
数据结构:
来自:https://blog.csdn.net/TheWayForDream/article/details/118436732
用一个数组t[x]存储以x为根节点的点的sum
1,可以发现所有同深度的节点的lowbit值都相等
2,子节点 x 的父节点为:x + lowbit(x)
3,计算前x项(0 - x项)为
for(int i=x;i;i-=lowbit(i))
{
sum+=t[i];
}
4,计算 i 到 j 只需要计算前 i - 1 项然后用前 j 项减去即可{ sum(j) - sum(i-1) }
5,加入或删除数值均只需要加减本位和所有父为即可
极简代码:(数组从1开始,0位赋值位0)
#include <bits/stdc++.h>
using namespace std;
int n;
int lowbit(int x)
{
return x&(-x);
}
int func(int e,int *t)//计算 0 - e 项和
{
int res = 0;
for(int i = e;i;i -= lowbit(i))
{
res += t[i];
}
return res;
}
int sum(int i,int j,int *t)//计算 i 到 j 项和
{
return func(j,t) - func(i-1,t);
}
void add_num(int e,int f,int *t)
{
for(int i = e;i <= ::n;i += lowbit(i))
{
t[i] += f;
}
}
int main()
{
cin >> ::n;
int t[999] = {};
for(int i = 1;i <= ::n;++i)
{
int num;
cin >> num;
add_num(i,num,t);
}
cout << sum(1,4,t);
return 0;
}