Article Directory
1. Fenwick tree
Similar data structure: segment tree (Segment Tree)
Fenwick tree with the tree line difference:
- Fenwick tree can do, segment tree can do! (Tree line features more cattle)
- Fenwick tree code is simple, easy to implement than the segment tree (tree code simpler array)
Query and modify complex array of tree are
- A former array is
- Fenwick tree is C
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
- To C8 (2 binary 8 is
1000
, there are three behind0
, so he was in possession with the number 3C4、C6、C7
, as well as their ownA8
) - No end of odd
0
, so odd bit only their own - Then how to calculate the number of tubes with a few numbers it?
2. Single point query, modify a single point
Tree array core function lowbit(int m)
: the role of obtaining a position m 1 binary representation of the end, to query for the prefix and m, m = m - lowbit(m)
on behalf of the end of the continuous binary 1 1 operation continuously performed until m == 0 completed, can be obtained which is composed of a prefix and a few Cm
int lowbit(int m){
return m & (-m);//(获取最后一个1的10进制值)
}
int getsum(int i){ //求A[1],A[2],...A[i]的和
int res = 0;
while(i > 0){
res += c[i];
i -= lowbit(i);
}
return res;
}
Eight ( 1000
) to count follows:
NOTE: negative binary numbers are positive end negated +1
8 & (-8) = 1000 & (.111..1000) = 1000 = 8....8-8=0,sum=C8=A[1]+..A[8]
-------------
6 & (-6) = 0110 & (1010) = 10 = 2 .... 6-2=4,sum=C6
4 & (-4) = 0100 & (1100) = 100 = 4.....4-4=0,sum+=C4=C6+C4=A[1]+...A[6]
-------------
奇数上面操作结果均为 1
#include <bits/stdc++.h>
using namespace std;
int n = 8;
int a[9]={-1,1,2,3,4,5,6,7,8}, c[9] = {0}; //对应原数组和树状数组
int lowbit(int x){
return x&(-x);
}
void update(int i, int delta){ //在i位置加上delta
while(i <= n){
c[i] += delta;
i += lowbit(i);
}
}
int getsum(int i){ //求A[1],A[2],...A[i]的和
int res = 0;
while(i > 0){
res += c[i];
i -= lowbit(i);
}
return res;
}
int main(){
for(int i = 1; i < 9; ++i)
update(i,a[i]);//读取原数据,插入树状数组
cout << getsum(3) << endl;//获取前3个数的和
cout << getsum(8) << endl;
update(3,2);
cout << getsum(3) << endl;
cout << getsum(8) << endl;
cout << getsum(4)-getsum(2) << endl;//获取A[3],A[4]的区间和
return 0;
}
result:
6
36
8
38
9
3. Single point query, modify the interval
After the update learning.
- Related Title: Programmer Interview Golden - 10.10 rank face questions digital stream (map / Fenwick tree)
Reference :