The previous section is a line segment tree. It is based on the interval binary method. Although the space requirement is O (n), it may take up to 4 * n arrays. It is more expensive to write. If the requirement is simple, you can use a lightweight data structure. The tree array is a binary indexed tree, which reflects its essence.
Copy something from Byvoid's blog and the work of Noi gold medalist. We strongly recommend www.byvoid.com/blog
A tree array is a small and elegant data structure. In many cases, it can replace the line tree. In a word, all the problems that can be solved by tree Arrays can be solved by the line tree. In turn, the problems that can be solved by the line tree may not be solved by the tree array.
The English name of the tree array isBinary Index Tree.Binary Index TreeI think the Binary Index Tree can better illustrate its nature. In essence, a tree array is a kind of data structure that maintains a sequence prior to I and through binary bits.
For the maintained sequence a, define C [I] = A [J + 1] +... + A [I]. In the binary representation where J is I, replace 1 on the rightmost with 0. The value of J can be obtained through lowbit, that is, I-lowbit (I ).
Lowbit (a) is 2 ^ (the binary value of A indicates the number of 0 at the end ). You can use the following formula to obtain
A &((~ A) + 1)
Or, it can be simplified to a &-A based on the nature of the complement.
Modification method:
void modify(int p,int delta) { while (p<=N) { C[p]+=delta; p+=lowbit(p); } }
Prefix and:
int sum(int p) { int rs=0; while (p) { rs+=C[p]; p-=lowbit(p); } return rs; }
The quotation is complete. The fill chart intuitively shows the tree array. The sum method code is provided.
The biggest advantage of tree arrays is the convenience of high-dimensional expansion. Take a two-dimensional tree array as an example. In one-dimensional scenarios, C [I] = A [I-lowbit (I) + 1] +... + A [I], to two dimensions, naturally C [I, j] should be from C [I-lowbit (I + 1) + 1] [J-lowbit (j) + 1] rectangular area. Continue to steal images. This is Hu Weidong's senior student. It shows the splitting of the Two-dimensional tree array of 15*15:
Take an example to illustrate the specific operation. Poj1195
The question is a two-dimensional array of S * s. You can increase or decrease any element in the array and find the sum of any rectangle blocks. First, the rectangular block starting from the origin can be obtained through a double loop. For any rectangle, Li, LJ, hi, HJ can be converted into four prefixes and ,.
Code on
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cmath>using namespace std;typedef long long int64;#define lowbit(x) ((x)&(-x))const int BITREE_SIZE_MAX=1025;int bitree_size;int bitree_2d[BITREE_SIZE_MAX+1][BITREE_SIZE_MAX+1];void bitree_init_2d(int size){bitree_size=size;for(int i=1;i<=size;++i){memset(bitree_2d[i]+1,0,size*sizeof(int));}}void bitree_change_2d(int i,int j,int dif){int j_init=j;while(i<=bitree_size){j=j_init;while(j<=bitree_size){bitree_2d[i][j]+=dif;j += lowbit(j);}i += lowbit(i);}}int64 bitree_sum_2d(int i,int j){if(i==0 || j==0){return 0;}int64 r=0;int j_init=j;while(i>0){j=j_init;while(j>0){r+=bitree_2d[i][j];j -= lowbit(j);}i -= lowbit(i);}return r;}int64 bitree_sum_2d(int li,int lj,int hi,int hj){return bitree_sum_2d(hi,hj) - bitree_sum_2d(li-1,hj)-bitree_sum_2d(hi,lj-1)+bitree_sum_2d(li-1,lj-1);}int main(){//freopen("in.txt","r",stdin);int op;int pa,pb,pc,pd;cin>>op>>pa;bitree_init_2d(pa);while(true){/*for(int i=1;i<=bitree_size;++i){for(int j=1;j<=bitree_size;++j){cout<<bitree_sum_2d(i,j)<<' ';}cout<<endl;}*/scanf("%d",&op);switch(op){case 1:scanf("%d%d%d",&pa,&pb,&pc);bitree_change_2d(pa+1,pb+1,pc);break;case 2:scanf("%d%d%d%d",&pa,&pb,&pc,&pd);cout<<bitree_sum_2d(pa+1,pb+1,pc+1,pd+1)<<endl;break;default:return 0;}}return 0;}
The next section is a special case of the rmq problem. monotonous queues are used.
Bytes ------------------------------------------------------------------------------------------------------------------
My blog: http://www.npbool.info