树状数组,数组a是原数组,下面是他们的一些关系
数组C就是
C1=a1
C2=a1+a2
C3=a3
C4=a1+a2+a3+a4
C5=a5
……
C8=a1+a2+a3+a4+a5+a6+a7+a8
……
C2^n=a1+a2+….+a2^n
那么树状数组具体怎么定义的呢?思考上面的规律,不难得出结论:
对于序列a,我们设一个数组C定义C[i] = a[i – 2^k + 1] + … + a[i],k为i在二进制下末尾0的个数。
这个C就是树状数组。
2^K的计算很简单:x & -x(网上还有其他版本,如2^k=x and (x xor (x-1)) ,但这个是最简单的了,如果位运算不太理解,记下来就行了)
//
树状数组(Binary Indexed Tree)
// 构造函数:
// BIT(int n) 初始化一个最大下标为n的树状数组
// 操作
// modify(int k, int value):将第k个元素修改为value
// sum(k):计算前k个元素的和
// sum(a, b):计算第a个元素到第b个元素的和
// get(k):返回第k个元素的值
class BIT
... {
private:
int *C;
int size;
//用于计算2^k,其中k为x在二进制下末尾0的个数
//这样写的理由~~~背下来就行了,反正x & -x很好记
inline int lowbit(int x)
...{
return (x & -x);
}
public:
//构造函数,初始化一个BIT
BIT(int n)
: size(n), C(new int[n+1])
...{
memset(C, 0, sizeof(int)*(n+1));
}
//将第k个元素的值改为val
//算法请联系BIT的定义自行思考,或者背下来
inline void modify(int k, int val)
...{
while (k <= size)
...{
C[k] += val;
k += lowbit(k);
}
}
//求前k个元素的和,联系定义,很容易明白
//背下来也可以
inline int sum(int k)
...{
if (k == 0)
return 0;
int t = 0;
while (k > 0)
...{
t += C[k];
k -= lowbit(k);
}
return t;
}
//返回第a到b个元素的和
inline int sum(int a, int b)
...{
return sum(b) - sum(a-1);
}
//返回第index个元素
inline int get(int index)
...{
return sum(index) - sum(index-1);
}
} ;
// 构造函数:
// BIT(int n) 初始化一个最大下标为n的树状数组
// 操作
// modify(int k, int value):将第k个元素修改为value
// sum(k):计算前k个元素的和
// sum(a, b):计算第a个元素到第b个元素的和
// get(k):返回第k个元素的值
class BIT
... {
private:
int *C;
int size;
//用于计算2^k,其中k为x在二进制下末尾0的个数
//这样写的理由~~~背下来就行了,反正x & -x很好记
inline int lowbit(int x)
...{
return (x & -x);
}
public:
//构造函数,初始化一个BIT
BIT(int n)
: size(n), C(new int[n+1])
...{
memset(C, 0, sizeof(int)*(n+1));
}
//将第k个元素的值改为val
//算法请联系BIT的定义自行思考,或者背下来
inline void modify(int k, int val)
...{
while (k <= size)
...{
C[k] += val;
k += lowbit(k);
}
}
//求前k个元素的和,联系定义,很容易明白
//背下来也可以
inline int sum(int k)
...{
if (k == 0)
return 0;
int t = 0;
while (k > 0)
...{
t += C[k];
k -= lowbit(k);
}
return t;
}
//返回第a到b个元素的和
inline int sum(int a, int b)
...{
return sum(b) - sum(a-1);
}
//返回第index个元素
inline int get(int index)
...{
return sum(index) - sum(index-1);
}
} ;