A tree array is a useful data structure that changes an element and sums it to an array. Both operations are O (LOGN).
The complexity of element modification and continuous element summation for a traditional array (n elements) is O (1) and O (n), respectively. The tree-like array transforms the linear structure into a pseudo-tree structure (linear structures can scan the elements individually, and the tree structure allows for a jump scan), which makes the modification and summation complexity both O (LGN), greatly improving the overall efficiency.
Given a sequence (series) A, we set an array C to satisfy
C[i] = a[i–2^k+ 1] + ... + a[i]
where k is the number of I at the end of the binary 0, I start from 1 to calculate.
Then we call c a tree-like array.
The question below is, given I, how do I ask for 2^k?
The answer is simple:2^k=i& (i^ (i-1)), which is i& (-i). Please see below:
Integer Operation x& (-X), the result of which is 1;x is the maximum quadratic factor of 2 in X when the result is 0;x is odd for the result of 0 o'clock.
because: X & (×) is the bitwise of the integer x with its inverse number (minus): 1&1=1,0&1 =0, 0&0 = 1. The specific analysis is as follows:
-When x is 0 o'clock,x& (-X) is 0 & 0, the result is 0;
-When x is not 0 o'clock, X and-X. must have a positive. Without losing its generality, set X as positive.
When x is an odd number, the last bit is 1, and the inverse plus 1 does not carry, so X and X. Are the opposite of the last bit, and the bitwise and the result is 0. The last one is 1, so the result is 1.
When x is an even number and is 2 m (m>0), only one of the binary representations of X is 1 (from right to left) with M bit 0 on the right, and 0 on the left (the number is determined by the number of bytes representing x), so x takes the inverse plus 1, from right to left there are M 0, the m+1 and the left are all 1, and the first m+1 。 So,x& (-X) gets the X.
You can write x= y * (2^k) When x is an even number, but not a 2 m-time form. Where the lowest bit of Y is 1. The fact is that x is represented by an odd left-shift K-bit. At this point, the binary representation of X has K 0 on the rightmost, and the k+1 bit from right to left is 1. When x is reversed, the rightmost K-bit 0 becomes 1, the first k+1 to 0, and 1, the right-most K-bit becomes 0, and the k+1 position is 1 because of the rounding relationship. The left bit has no carry, just the opposite of the value on the corresponding bit of x. The two are bitwise AND, get: The first k+1 bit is 1, the left right side is 0. The result is 2^k, which is the maximum factor of 2 that is contained in X.
Summing up the:x& (-X), the result is a factor of 2 in X if the result is an even number when the result is 0;x is an odd number at 0 o'clock. For example, X=32, where 2 of the maximum quadratic factor is 2^5, so the x& (-X) result is 32, when x=28, where 2 of the maximum quadratic factor is 4, so the X & (×) result is 4. When X=24, where 2 of the maximum quadratic factor is 8, the x& (-X) result is 8.
The following explanation:
Take I=6 as an example (note: a_x indicates that the number a is an X-binary representation):
(i) _10 = (0110) _2
(i-1) _10= (0101) _2
I xor (i-1) = (0011) _2
I and (I xor (i-1)) = (0010) _2
2^k = 2
C[6] = c[6-2+1]+...+a[6]=a[5]+a[6]
The exact meaning of array C is shown in the following figure:
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], the complexity of this operation in the worst case is the height of the tree is O (logn). In addition, for the first n of the sequence number and, just find all of the largest subtree before n, the root of the node C together. It is not difficult to find that the number of these subtrees is n at the binary 1 number, or the number of the power of the N expansion into 2 and the time, so the complexity of the sum operation is also O (Logn).
The tree array can quickly find any interval of sum: a[i] + a[i+1] + ... + a[j], set sum (k) = A[1]+a[2]+...+a[k], then a[i] + a[i+1] + ... + a[j] = SUM (j)-sum (i-1).
Here are the other people's summary of the topic and code (for reference):
HDU 1541 Stars
Test instructions: slightly.
Ideas:
A tree-like array of classic entry questions.
Ans[i]: The amount of stars of the level I;
Sum[i]: The point of the x-axis to meet the amount of the stars;
Note the place:
(1) The points given in the topic have been sequenced.
(2) Since x may take 0, and lowbit (0) = 0, add (0,1) will die loop. That's why I started the tle. So will all the X + +.
const int MAX1 = 15555, MAX2 = 32222;
int ANS[MAX1], sum[max2], n,x,y;
int lowbit (int x) {
return x & (-X);
}
int getsum (int pos) {
int ret = 0;
while (pos > 0) {
ret + = Sum[pos];
pos-= Lowbit (POS);
}
return ret;
}
void Add (int pos, int num) {
while (pos < MAX2) {
Sum[pos] + = num;
pos + = Lowbit (pos);
}
}
int main ()
{while
(scanf ("%d", &n)! = EOF) {
memset (sum, 0, sizeof (sum));
memset (ans, 0, sizeof (ans));
for (i,1,n) {
scanf ("%d%d", &x, &y);
x + +; Note Add 1 or else the
ans[getsum (x)]++ will be executed in Add (0,1);
Add (x, 1);
}
for (i,0,n-1)
printf ("%dn", Ans[i]);
}
return 0;
}
POJ 2182 Lost Cows
Test instructions: There is a sequence a:1,2,..., N (2 <= n <= 8,000). Now the sequence is chaotic, known as the number of a[i] in front of the number of the first is less than it. Find out how the sequence is arranged.
Idea: Pushed forward by the rear. The true value of the last number is a[n]+1. Delete a[n]+1 in sequence, update a[i], then the true value of N-1 number is a[n-1]+1. This analogy.
Because of the small data range, a two-tier for-loop simple method can be solved.
Here is a solution to the tree array:
const int MAX = 8010;
int A[max], n, Cnt[max], Ans[max];
int lowbit (int x) {return x & (-X),} void Add (int pos, int val) {while (pos <= n) {Cnt[pos] + = val;
pos + = Lowbit (POS);
}} int sum (int pos) {int res = 0;
while (pos > 0) {res + = Cnt[pos];
pos-= Lowbit (POS);
} return res;
}//Two points find the first position equal to x int binary_search (int x) {int low = 1, high = N, mid;
while (low <= high) {mid = (low + high) >> 1;
int k = SUM (mid);
if (k >= x) high = mid-1;
else low = mid+1;
} while (sum (mid) < x) mid++;
return mid;
} int main () {while (scanf ("%d", &n)! = EOF) {a[1] = 0;
for (I,2,n) scanf ("%d", &a[i]);
memset (CNT, 0, sizeof (CNT));
for (i,1,n) Add (i,1);
for (int i = n; I >= 1; i--) {Ans[i] = Binary_search (a[i]+1);
Add (Ans[i],-1);
} for (I,1,n) printf ("%d\n", Ans[i]); } return 0; }
POJ 2481 Cows
Test Instructions: two intervals: [Si, Ei] and [Sj, Ej]. (0 <= S < E <= 105). If Si <= Sj and Ej <= Ei and Ei–si > EJ–SJ, then the section I is covered by section J interval. Given n intervals (1 <= n <= 10^5), it is found out how many intervals can be overridden for the first interval.
idea: It seems quite complicated at first glance. You can actually think of the interval [s, E] as a point (s, e), so the title translates into Hdu 1541 Stars. Just here is the number of points at the top left of the point.
However, I still have a lot of WA, some of the details did not notice. When ordering a point, it is sorted by y from large to small, and then by X from small to large. You can't sort by x first. Example N=3, [1,5], [1,4], [3,5]. Also pay attention to the treatment of the same point.
const int MAX = 100010; struct node{int x, y, id, ans;}
Seq[max];
int Sum[max], n;
int cmp1 (const void *n1, const void *N2) {int res = ((node*) n2)->y-((node*) N1)->y;
if (res = = 0) return ((node*) N1)->x-((node*) n2)->x;
else return res;
} int cmp2 (const void *n1, const void *N2) {return ((node*) N1)->id-((node*) n2)->id;} int lowbit (int x) {return x & (-X);} void Add (int pos, int val) {while (pos < MAX) {//I am always accustomed to write N, Wasted a lot of time.
is actually the maximum range of horizontal x.
Sum[pos]+=val;
Pos+=lowbit (POS);
}} int getsum (int pos) {int res = 0;
while (pos>0) {Res+=sum[pos];
Pos-=lowbit (POS);
} return res; } int main () {while (scanf ("%d", &n) && N) {for (i,1,n) {scanf ("%d%d", &seq[i].x,
&SEQ[I].Y);
seq[i].x++, seq[i].y++;
Seq[i].id = i;
} qsort (seq+1, N, sizeof (Node), CMP1);
memset (sum, 0, sizeof (sum));Seq[1].ans = 0;
Add (seq[1].x, 1);
int fa = 1; for (I,2,n) {if (seq[i].x = = seq[fa].x && seq[i].y = = seq[fa].y) {Seq[i].ans = Seq[fa].a
ns
}else{FA = i;
Seq[i].ans = Getsum (seq[i].x);
} Add (seq[i].x, 1);
} qsort (seq+1, N, sizeof (Node), CMP2);
printf ("%d", Seq[1].ans);
for (i,2,n) printf ("%d", Seq[i].ans);
printf ("\ n");
} return 0; }
POJ 2155 Matrix
Classical problems of two-dimensional tree-like arrays
Test instructions: To a n*n matrix, where the value is not 0, or 1. The initial value of each lattice is 0.
There are two types of operations on the matrix: (Total T)
1.C x1 y1 x2 y2: The upper-left corner is (x1, y1), and the lower-right corner is (x2, y2) the values in the sub-matrix of this range are all reversed.
2.Q x y: The value of row I, column J in the query matrix.
(2 <= N <=, 1 <= T <= 50000)
Ideas: See National Training Team paper: Takemori on "0" and "1" in the competition of informatics
1. The number of the matrices described in this topic is not 1 or 0, so we can determine the number of the lattice by simply recording how many times each lattice has changed.
2. Consider one-dimensional conditions first:
To modify the values of the [x, y] interval, you can actually modify the values of both the X and Y+1 points (add 1 to the values of the two points). When querying the value of K-point, its number of modifications is sum (cnt[1] + ... + cnt[k]).
3. Two-dimensional situation:
The same dimension of truth. To modify the range [x1, y1, x2, y2], simply modify these four points: (X1,y1), (x1,y2+1), (X2+1,y1), (x2+1,y2+1). When querying the value of a point (x, y), its number of modifications is sum (cnt[1, 1, x, Y]).
4. When the interval is summed, it can be implemented by a tree-like array.
const int MAX = 1010;
int n, Cnt[max][max]; int lowbit (int x) {return x & (-X);} void Add (int x, int y, int val) {for (int i = x; i <= n; i + = Lowbit (i
)) for (int j = y; J <= N; j + = Lowbit (j)) Cnt[i][j] + = val;
} int sum (int x, int y) {int res = 0;
for (int i = x; i > 0; I-= Lowbit (i)) for (int j = y; j > 0; J-= Lowbit (j)) Res + = Cnt[i][j];
return res;
} int main () {int T, M, x1, y1, x2, y2;
Char op[10];
CIN >> T;
while (t--) {scanf ("%d%d", &n, &m);
memset (CNT, 0, sizeof (CNT));
while (m--) {scanf ("%s%d%d", op, &x1, &y1);
if (op[0] = = ' C ') {scanf ("%d%d", &x2, &y2);
Add (x1, y1, 1);
Add (x1, y2+1, 1);
Add (x2+1, y1, 1);
Add (X2+1, y2+1, 1);
}else{printf ("%d\n", sum (x1,y1)% 2); }} printf ("\ n "); }
}