Tree-like array full network detailed explanation

Source: Internet
Author: User

Tree-like array concept:

A tree-like array is a very good & magical data structure. Can do interval query, single-point modification, the complexity of both operations are log (n), the spatial complexity of O (n).

The key to understanding the tree array is to understand the binary, there was a great God said to me: "This world is a binary system, people should not be subjective to build a decimal", I do not have the ability to prove the correctness of this sentence, But I think this sentence in a tree-like array is very helpful to understand (because this data structure is based on the binary).

First from Baidu to borrow a picture, yes, the red part is the legendary tree-like array.

observing for a moment, it is not difficult to find:

  C1 = A1  C2 = A1+A2  C3 = A3  C4 = A1+A2+A3+A4  C5 = A5  C6 = A5+A6  C7 = A7  C8 = A1+A2+A3+A4+A5+A6+A7+A8

  But why is there such a rule? Of course it is because of the wonderful principle of the tree-like array.

Principle:

  Referring to the tree-like array principle, the first thing we think about is the Lowbit function, which runs through all the functions and implementations of the tree array, as well as the key to understanding the tree array.

Lowbit ():

  Open a tree-like array of code, we can definitely find a macro definition or function, such as:

#define lowbit (x) (x&-x)               // macro definition notation int lowbit (intreturn x&-x; }   // function notation

 The two types of writing are obviously the same, but many oiers do not understand why it is written, but simply recite the code. The understanding of lowbit involves the most fundamental principles of a tree-like array. Let's see, give me a chestnut.

Chestnut: We take c[7] as an example, how do we judge the range of the c[6] represented by the interval?

First write c[7] binary: 0111, and then take the binary under the number from the right-to-left first 1 and the following 0 out, get 1, that is, 1 under the decimal, that is, c[7] contains the interval range length. In fact, 7 per 1 of the converted binary represents a node on the tree array. To simulate, we want to take the last 1 and 0 out, 0111 can be regarded as 0110+0001, 0110 to decimal equals 6, then c[7] range is [6 + 1, 7], the same way continue to seek c[6], 0110 = 0100 + 0010 When 0100 is converted to decimal and equals 4, the range of c[6] is [4 + 1, 6]. Finally, ask for the range of c[4] (a bit special) 0100 = 0100 + 0000 0000 to decimal equals 0, then the range of c[4] is [0 + 1, 4].

See this, the crux of the problem is only then take a number from the right-to-left first 1 and then 0 out, that is, what the Lowbit function does.

Lowbit () What the hell is this line of code doing? We need to understand some small knowledge first.

1, anti-code = The original code every bit reverse.

2, complement = anti-code + 1.

3, the computer, negative numbers using the complement to express.

Then look at the code above:

return x &-X;

 We take 76 as an example, let's do the above Operation & 76

After ignoring the sign bit, the effect is as follows:

76 Turn binary: 0100 1100

-76 binary: 1011 0100

  0100 1100

& 1011 0100

= 0000 0100

  The magic has been accomplished.

Does that make sense? There must be, because the inverse code = The original code to take the reverse complement = inverse code + 1, then the complement and the original code in addition to the last 1, the rest must be the opposite, and the operation is 0. And finally add 1 times, will make the end of a paragraph again, until the encounter 0, cannot carry up so far, and the first encounter of 0, must be the original code from right to left the first 1.

Finally we also conclude that c[l] contains a number of a[i-lowbit (i) + 1] ~ a[i] Total lowbit (i) numbers.

Interval query:

First of all, the tree array itself maintains the interval, but one problem with queries is that the query interval is not necessarily the entire interval maintained by the tree array.

For example, we require intervals [4,7] and.

So we first use the prefix and the idea, the problem is simplified to the [1,7] of the interval and-[1,4] interval and.

Then we consider the [1,n] interval and the method of finding: We know that the node on the tree array C[i] represents the and of a[i-lowbit (i) + 1] to a[i] on the original array, then we are considering the interval of 1~n and the last ans must not contain a[n + 1], and not a[n + 1] The location of our preferred C[n] (C[n] contains the interval must be c[n + 1] before), now ans + + c[n] We have already counted some of the answers, we also know that we have just the statistical answer must be the original array of A[i-lowbit (n) + 1] to a[n, total L The number of Owbit (n) is counted, and the problem is converted to the interval of [1,n-lowbit (n)]. And so on, we can find out the interval of [1,n] by Lowbit.

Summary: Sum[i][j] = sum[1][j]-sum[1][i];

for (int i = n; I! = 0; I-= Lowbit (i)) ans + = c[i];

Sum[1][n] = ans;

The code is as follows:

int Query (int  x) {    int0;      for (int i = x; i; I -= Lowbit (i))//note cyclic termination        conditions + = Tree[i]    ; return sum;}

Single-point modification:

since the tree array maintains the prefix and when we make a single point modification, we also consider modifying the points that contain the node, and when all of these points have been modified, a single point of modification is completed.

Give a chestnut: We modify the P element. We need to find a lot of c[i that contain p] and change them all. So those c[i] need to be modified?

The first need to modify the C[i] number must be greater than p, the range must include P, and lowbit (i) must be greater than Lowbit (P).

So we draw I >= P > i-lowbit (i)

We set the binary of P to 0101 1010

Let's start with a little bit of speculation about how much I might be.

Set I for ABCD Efgh, since lowbit (i) must be greater than lowbit (P), I was given an ABCD ef00, after two bits were determined. The other six-bit if it is not 1 may also be 1 (because the original is 1 words push I will be less than P), if at this time F = 0, and because P > i-lowbit (i) We know that I is 0101 1100 (in order to meet the P > i-lowbit (i)).

We continue to roll out ABCDE for the 1 case, same as the last 1 followed by the same as P in front of 0,1.

We list all possible:

0101 1100

0110 0000

1000 0000

We find that these meet the requirements of I are found by constantly adding their own lowbit.

Yes, that's it!!! (Escape!) everyone can enumerate and try.

The code is as follows:

void ADD (intint  k) {    for (int i = x; i <= n; i + =  lowbit (i))//note cyclic termination conditions c8/>+ = k;}

Code implementation:

By the way, the initialization of the tree array: just use single-point modification to do it. No problem.

#include <iostream>#include<cstdio>#defineLowbit (x) (x&-x)Const intmaxn=500010;intn,m;intx, y, zintTREE[MAXN];voidADD (intXintk) {     for(inti=x;i<=n;i+=lowbit (i)) Tree[i]+=K;}intQuery (intx) {    intsum=0;  for(inti=x;i;i-=lowbit (i)) sum+=Tree[i]; returnsum;}intMain () {scanf ("%d%d",&n,&m);  for(intI=1; i<=n;++i) {scanf ("%d",&x);    ADD (I,X); }     for(intI=1; i<=m;++i) {scanf ("%d%d%d",&x,&y,&z); if(x==1) Add (y,z); ElseStd::cout<<query (z)-query (y1) <<Std::endl; }    return 0; }

Summary:

A tree-like array is indeed a graceful to stunning data structure. But it is not omnipotent, there are many advantages but also have shortcomings.

Advantages: Simple code, good writing, good tune. Modify query time complexity is O (Logn), and the constant is smaller than the segment tree.

Disadvantage: Must satisfy the interval subtraction, must convert to two prefix subtraction. This makes it impossible to solve many problems with a tree-like array.

                           

Tree-like array full network details

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.