高级数据结构
1. 树状数组
名曰树状数组,那么究竟它是树还是数组呢?数组在物理空间上是连续的,而树是通过父子关系关联起来的,而树状数组正是这两种关系的结合,首先在存储空间上它是以数组的形式存储的,即下标连续;其次,对于两个数组下标 ,如果 ( 等于 的二进制表示中末尾0的个数),那么定义 为一组树上的父子关系,其中 为父结点, 为子结点。
然后我们来看树状数组上的结点Ci具体表示什么,这时候就需要利用树的递归性质了。我们定义Ci的值为它的所有子结点的值 和 Ai 的总和,之前提到当i为奇数时Ci一定为叶子结点,所以有Ci = Ai ( i为奇数 )。
C1 = A1
C2 = C1 + A2 = A1 + A2
C3 = A3
C4 = C2 + C3 + A4 = A1 + A2 + A3 + A4
C5 = A5
C6 = C5 + A6 = A5 + A6
C7 = A7
C8 = C4 + C6 + C7 + A8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
我们从中可以发现,其实Ci还有一种更加普适的定义,它表示的其实是一段原数组A的连续区间和。
树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)作为一个查询和修改复杂度都为 的数据结构。下面我们就看一下这两个操作的具体实现:
求和操作
查询 的和,即为
int sum(int x){
int s = 0;
for(int i=x;i;i-=lowbit(i))
s += c[i];
return s;
}
更新操作
void add(int x, int v){
for(int i=x;i<=n;i+=lowbit(i))
c[i] += v;
}
lowbit函数实现
int lowbit(int x){
return x&(-x);
}
1.1 PUIQ模型
单点更新,区域查询(标准的树状数组)
- HDU 1166 - 敌兵布阵
- POJ 3321 - Apple Tree(将图转换为树状数组)