You can consider using a tree array when you want to make frequent changes to the array elements, while also frequently querying the sum of any interval elements within a set. Usually the most straightforward algorithm for a one-dimensional array can be modified in O (1) time, but an O (n) time is required to make a query. The modification and query of the tree array can be done in O (log (n)) time. First, recalling a one-dimensional tree array assumes that the one-dimensional array is a[i] (i=1,2,... N), then it corresponds to the tree array C[i] (i=1,2,... N) is defined as: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 + A4 C 5 = A5 C6 = A5 + a6c7 = A7 C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 ... C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16 ... (1) C[t] How many items are there after the expansion? Calculated by the following formula: int lowbit (int t) {//calculation C[t] expanded number of items return t& (-T); } C[t] Expands the number of items that are lowbit (t), C[t] is the number of lowbit (T) from the beginning of a[t] to the left. (2) Changes such as modified A3, must be modified C3,C4,C8,C16,C32,C64 ... When we modify the value of a[i], we can go upstream from c[i] to the root node, adjust all c[on this path], for node I, parent node subscript p=i+lowbit (i)//to A[i] plus x, update a series of c[j] Update (int i,int x) {W Hile (i<=n) {c[i]=c[i]+x; I=i+lowbit (i); }} (3) for the first n of the sequence a[], just find all the largest subtree of N and add up the C of its root node. such as: Sun (1) =c[1]=a[1]; Sun (2) =c[2]=a[1]+a[2]; Sun (3) =c[3]+c[2]=a[1]+a[2]+a[3]; Sun (4) =c[4]=a[1]+a[2]+a[3]+a[4]; Sun (5) =c[5]+C[4]; Sun (6) =c[6]+c[4]; Sun (7) =c[7]+c[6]+c[4]; Sun (8) =c[8]; ,,,,,, int Sum (int n)//For the sum of the first n items. {int sum=0; while (n>0) {sum+=c[n]; N=n-lowbit (n); } return sum; } lowbit (1) =1 lowbit (2) =2 lowbit (3) =1 lowbit (4) =4 lowbit (5) =1 lowbit (6) =2 Lowbit (7) =1 Lowbit (8) =8 Lowbit (9) =1 Lowbit (Ten) =2 lowbit (one) =1 lowbit (a) =4 lowbit (+) =1 lowbit (+) =2 low Bit (=1) lowbit (+) =16 lowbit (+) =1 lowbit (+) =2 lowbit (+) =1 lowbit (a) =4 lowbit (+) =1 lowbit (29) =2 Lowbit (+) =1 lowbit (=8 lowbit) =1 lowbit (+) =2 lowbit (=1 lowbit) =4 lowbit =1 Lowbit (36) =2 Lowbit (+) =1 lowbit (+) =32 lowbit (a) =1 lowbit () =2 lowbit (+) =1 lowbit ) =4 Lowbit (PNS) =1 lowbit (max) =2 lowbit (All) =1 lowbit (+) =8 lowbit (43) =1 Lowbit Lowbit (44)=4 Lowbit (51) =1 Lowbit (+) =2 lowbit () =1 lowbit ($) =16 lowbit ($) =1 lowbit (+) =2 lowbit () =1 Lowbit (=4 lowbit) =1 lowbit (SI) =2 lowbit (58) =1 Lowbit ($) =8 Lowbit (=1 Lowbit (=1 lowbit) =4 lowbit (All) =1 lowbit ($) =2 lowbit (+) =1 lowbit (64) =64====================== ============================= Two, the tree array can be extended to two dimensions. Problem: A large matrix composed of numbers, can do two operations 1) on a matrix of a number plus an integer (can be positive negative) 2) query a sub-matrix of all the numbers and, requirements for each query, output results. A one-dimensional tree array can easily be extended to two dimensions, in two-dimensional cases: the array a[][] is defined as a tree-like array: C[x][y] =∑a[i][j], where X-lowbit (x) + 1 <= i <= x, Y-lowbit (y) + 1 <= J <= Y. Example: Take a look at the composition of c[][]. Set the original two-dimensional array to: A[][]={{a11,a12,a13,a14,a15,a16,a17,a18,a19}, {a21,a22,a23,a24,a25,a26,a27,a28,a29}, {A31,a3 2,a33,a34,a35,a36,a37,a38,a39}, {a41,a42,a43,a44,a45,a46,a47,a48,a49}}; So it corresponds to a two-dimensional tree-like array c[][]? Note: B[1]={a11,a11+a12,a13,a11+a12+a13+a14,a15,a15+a16,...} This is the first row of a one-dimensional tree array b[2]={a21,a21+a22,a23,a21+a22+a23+a24,a25, A25+a26,...} This is the second row of a one-dimensional tree array b[3]={a31,a31+a32,a33,a31+a32+a33+a34,a35,a35+a36,...} This is a one-dimensional tree array of the third row b[4]={a41,a41+a42,a43,a41+a42+ A43+a44,a45,a45+a46,...} This is the fourth row of a one-dimensional tree array then: C[1][1]=a11,c[1][2]=a11+a12,c[1][3]=a13,c[1][4]=a11+a12+a13+a14,c[1][5]=a15,c[1][6]=a15+a16,... This is a one-dimensional tree array of the first row of a[][] c[2][1]=a11+a21,c[2][2]=a11+a12+a21+a22,c[2][3]=a13+a23,c[2][4]=a11+a12+a13+a14+a21+a22+a23+ A24, C[2][5]=a15+a25,c[2][6]=a15+a16+a25+a26,... This is the a[][] array of the first row and the second row after the addition of the tree-like array c[3][1]=a31,c[3][2]=a31+a32,c[3][3]=a33,c[3][4]=a31+a32+a33+a34,c[3][5]=a35,c[3][6]= A35+a36,... This is a[][] the third row of a one-dimensional tree array c[4][1]=a11+a21+a31+a41,c[4][2]=a11+a12+a21+a22+a31+a32+a41+a42,c[4][3]=a13+a23+a33+a43,... This is the a[][] array the first row + the second row + the third row + the fourth row after the tree-like array to find out the two-dimensional tree array c[][] law? After a closer look, you will find: (1) in two-dimensional cases, if A[i][j]=delta is modified, the corresponding two-dimensional tree array update function is: private void Modify (int i, int j, int delta) { A[i][j]+=delta; for (int x = i; x< a.length; x + = Lowbit (x)) for (int y = j; y <A[i].length; y + = lowbit (y)) {c[x][y] + = Delta; }} (2) in two-dimensional case, the function of the sum of the ∑a[i][j] (the first row and the first J column) is int Sum (int i, int j) {int result = 0; for (int x = i; x > 0; X-= Lowbit (x)) {for (int y = j; y > 0; y-= Lowbit (y)) {result + = C[x][y]; }} return result; } For example: Sun (=c[1][1)]; Sun (=c[1][2)]; Sun (1,3) =c[1][3]+c[1][2]; Sun (2,1) =c[2][1]; Sun (2,2) =c[2][2]; Sun (2,3) =c[2][3]+c[2][2]; Sun (3,1) =c[3][1]+c[2][1]; Sun (3,2) =c[3][2]+c[2][2];
PackageA two-dimensional tree-like array; Public classMainapp {int[] A;//original two-dimensional array int[] C;//corresponding two-dimensional tree-like array PublicMainapp () {A=New int[5] [6]; C=New int[5] [6]; for(inti=1;i<5;i++) for(intj=1;j<6;j++) Modify (I,j,1);//add 1 to a[][] per element for(inti=1;i<5;i++){ for(intj=1;j<6;j++) System.out.print (A[i][j]+" ");//output a[][]System.out.println (); } System.out.println (Sum (3,4));//the and of the two-dimensional arrays of childrenModify (2,3,4);//Add 4 to a[2][3]System.out.println (Sum (3,4));//Displays the modified and } Private intLowbit (intt) { returnt& (-t); } intSum (intIintj) { intresult = 0; for(intx = i; x > 0; X-=lowbit (x)) { for(inty = j; Y > 0; Y-=lowbit (y)) {Result+=C[x][y]; } } returnresult;} Private voidModify (intIintJintDelta) {A[i][j]+=Delta; for(intx = i; x< a.length; X + =lowbit (x)) for(inty = j; Y <A[i].length; Y + =lowbit (y)) {C[x][y]+=Delta; } } Public Static voidMain (string[] args) {Mainapp m=NewMainapp (); }}
Two-dimensional tree-like array