J E L L Y E N T
Phase Tree

A Phase Tree is a puny print constructing that allows answering fluctuate queries over an array effectively, while restful being versatile broad to enable modifying the array.
This entails discovering the sum of consecutive array facets $a[l dots r]$, or discovering the minimal element in a this form of fluctuate in $O(log n)$ time.
Between answering such queries the Phase Tree permits modifying the array by altering one element, or even swap the facets of an complete subsegment (e.g. assigning all facets $a[l dots r]$ to any rate, or adding a rate to all element within the subsegment).

In venerable a Phase Tree is a extraordinarily versatile puny print constructing, and a broad desire of complications would presumably presumably presumably presumably be solved with it.
It is miles miles on the overall also imaginable to note extra advanced operations and acknowledge extra advanced queries (ascertain Evolved variations of Phase Bushes).
Particularly the Phase Tree would presumably presumably presumably presumably be with out peril generalized to elevated dimensions.
Lets embody with a two-dimensional Phase Tree it is doubtless you are going to presumably presumably be interesting to acknowledge sum or minimal queries over some subrectangle of a given matrix.
Alternatively supreme in $O(log^2 n)$ time.

One most well-identified property of Phase Bushes is, that they require supreme a linear quantity of memory.
The well-preferred-or-backyard Phase Tree requires $4n$ vertices for engaged on an array of dimension $n$.

Easiest dispute of a Phase Tree

To plot easy, now we possess got in thoughts the most inviting dispute of a Phase Tree.
We’re browsing out for to acknowledge sum queries effectively.
The formal definition of our job is:
We possess got an array $a[0 dots n-1]$, and the Phase Tree wants in repeat to have the sum of facets between the indices $l$ and $r$ (i.e. computing the sum $sum_{i=l}^r a[i]$), and likewise take care of altering values of the facets within the array (i.e. luxuriate in assignments of the dispute $a[i] = x$).
The Phase Tree ought in repeat to job each queries in $O(log n)$ time.

Structure of the Phase Tree

So, what’s a Phase Tree?

We compute and retailer the sum of the facets of the total array, i.e. the sum of the fragment $a[0 dots n-1]$.
We then atomize up the array into two halves $a[0 dots n/2]$ and $a[n/2+1 dots n-1]$ and compute the sum of every halve and retailer them.
Each and every of these two halves in flip also atomize up in half of of, their sums are computed and saved.
And this job repeats except all segments reach dimension $1$.
In other phrases we plot with the fragment $a[0 dots n-1]$, atomize up most continuously the most modern fragment in half of of (if it has no longer yet become a fraction containing a single element), after which calling the identical blueprint for each halves.
For every such fragment we retailer the sum of the numbers on it.

We’re going to screech, that these segments dispute a binary tree:
the muse of this tree is the fragment $a[0 dots n-1]$, and every vertex (except for for leaf vertices) has precisely two little one vertices.
Right here’s why the puny print constructing is is named « Phase Tree », despite the indisputable fact that in most implementations the tree mustn’t be constructed explicitly (ascertain Implementation).

Right here’s a seen illustration of this form of Phase Tree over the array $a = [1, 3, -2, 8, -7]$:

From this swiftly description of the puny print constructing, we are able to already discover that a Phase Tree supreme requires a linear desire of vertices.
The treasured level of the tree comprises a single node (the muse), the 2nd level will admire two vertices, within the third this would presumably admire four vertices, except the want of vertices reaches $n$.
Thus the want of vertices within the worst case would presumably presumably presumably presumably be estimated by the sum $1 + 2 + 4 + dots + 2^{lceillog_2 nrceil} = 2^{lceillog_2 nrceil + 1} lt 4n$.

It is miles mark noting that at any time when $n$ mustn’t be a energy of two, no longer all levels of the Phase Tree would possibly possibly be completely stuffed.
We’re going to ascertain that habits within the image.
For now we are able to neglect about this truth, however this would presumably become most well-identified later within the future of the implementation.

The finish of the Phase Tree is $O(log n)$, because when going down from the muse to the leaves the scale of the segments decreases roughly by half of of.

Building

Sooner than setting up the fragment tree, now we possess got to discover:

  1. the rate that can gain saved at every node of the fragment tree.
    As an illustration, in a sum fragment tree, a node would retailer the sum of the facets in its fluctuate $[l, r]$.
  2. the merge operation that merges two siblings in a fraction tree.
    As an illustration, in a sum fragment tree, the 2 nodes akin to the ranges $a[l_1 dots r_1]$ and $a[l_2 dots r_2]$ would possibly possibly well per chance be merged trusty trusty into a node akin to the fluctuate $a[l_1 dots r_2]$ by adding the values of the 2 nodes.

Uncover that a vertex is a « leaf vertex », if its corresponding fragment covers supreme one rate within the recurring array. It is miles screech their deepest praises on the lowermost level of a fraction tree. Its rate would possibly possibly well per chance be equal to the (corresponding) element $a[i]$.

Now, for constructing of the fragment tree, we plot on the backside level (the leaf vertices) and dilemma up them their respective values. On the premise of these values, we are able to compute the values of the out of date level, the usage of the merge feature.
And on the premise of these, we are able to compute the values of the out of date, and repeat the blueprint except we reach the muse vertex.

It is miles at hand to describe this operation recursively within the opposite route, i.e., from the muse vertex to the leaf vertices. The enchancment blueprint, if called on a non-leaf vertex, does the subsequent:

  1. recursively comprise the values of the 2 little one vertices
  2. merge the computed values of these childhood.

We plot the vogue on the muse vertex, and subsequently, we are interesting to compute the total fragment tree.

The time complexity of this constructing is $O(n)$, assuming that the merge operation is persevering with time (the merge operation will gain called $n$ events, which is equal to the want of interior of nodes within the fragment tree).

Sum queries

For now we will acknowledge sum queries. As an input we receive two integers $l$ and $r$, and now we possess got to compute the sum of the fragment $a[l dots r]$ in $O(log n)$ time.

To elevate out this, we are able to traverse the Phase Tree and remark the precomputed sums of the segments.
Let’s take grasp of that we are currently on the vertex that covers the fragment $a[tl dots tr]$.
There are three imaginable circumstances.

The simplest case is when the fragment $a[l dots r]$ is equal to the corresponding fragment of most continuously the most modern vertex (i.e. $a[l dots r] = a[tl dots tr]$), then we are done and would presumably presumably presumably presumably return the precomputed sum that is saved within the vertex.

Alternatively the fragment of the ask can fall completely into the domain of either the left or the supreme little one.
Interact that the left little one covers the fragment $a[tl dots tm]$ and the supreme vertex covers the fragment $a[tm + 1 dots tr]$ with $tm = (tl + tr) / 2$.
In this case we are able to merely fade to the little one vertex, which corresponding fragment covers the ask fragment, and discover the algorithm described right here with that vertex.

After which there would presumably be the closing case, the ask fragment intersects with each childhood.
In this case now we possess got no other chance as to affect two recursive calls, one for every little one.
First we fade to the left little one, compute a partial acknowledge for this vertex (i.e. the sum of values of the intersection between the fragment of the ask and the fragment of the left little one), then fade to the supreme little one, compute the partial acknowledge the usage of that vertex, after which mix the answers by adding them.
In other phrases, for the explanation that left little one represents the fragment $a[tl dots tm]$ and the supreme little one the fragment $a[tm+1 dots tr]$, we compute the sum ask $a[l dots tm]$ the usage of the left little one, and the sum ask $a[tm+1 dots r]$ the usage of the supreme little one.

So processing a sum ask is a feature that recursively calls itself once with either the left or the supreme little one (with out altering the ask boundaries), or twice, once for the left and once for the supreme little one (by splitting the ask into two subqueries).
And the recursion ends, at any time when the boundaries of most continuously the most modern ask fragment coincides with the boundaries of the fragment of most continuously the most modern vertex.
If that is so the acknowledge most continuously is the precomputed rate of the sum of this fragment, which is saved within the tree.

In other phrases, the calculation of the ask is a traversal of the tree, which spreads thru all most well-identified branches of the tree, and makes remark of the precomputed sum values of the segments within the tree.

Obviously we are able to plot the traversal from the muse vertex of the Phase Tree.

The blueprint is illustrated within the subsequent image.
In all places all over again the array $a = [1, 3, -2, 8, -7]$ is susceptible, and right here we are browsing out for to compute the sum $sum_{i=2}^4 a[i]$.
The coloured vertices would possibly possibly be visited, and we are able to remark the precomputed values of the inexperienced vertices.
This provides us the final consequence $-2 + 1 = -1$.

Why is the complexity of this algorithm $O(log n)$?
To screech their deepest praises this complexity we search at every level of the tree.
It appears to be, that for every level we supreme consult with out a longer bigger than four vertices.
And for the explanation that top of the tree is $O(log n)$, we receive the specified working time.

We’re going to screech their deepest praises that this proposition (at most four vertices every level) is applicable by induction.
At the first level, we supreme consult with one vertex, the muse vertex, so right here we consult with decrease than four vertices.
Now let’s search at an arbitrary level.
By induction hypothesis, we consult with at most four vertices.
If we supreme consult with at most two vertices, the subsequent level has at most four vertices. That trivial, because every vertex can supreme reason at most two recursive calls.
So let’s take grasp of that we consult with three or four vertices in most continuously the most modern level.
From these vertices, we are able to compare the vertices within the center extra fastidiously.
For the explanation that sum ask asks for the sum of a valid subarray, all people knows that segments akin to the visited vertices within the center would possibly possibly be completely covered by the fragment of the sum ask.
As a outcomes of this truth these vertices mustn’t be going to affect any recursive calls.
So supreme most continuously the most left, and customarily the most trusty vertex will possess the aptitude to affect recursive calls.
And these will supreme gain at most four recursive calls, so also the subsequent level will fulfill the assertion.
We’re going to screech that one division approaches the left boundary of the ask, and the 2nd division approaches the supreme one.

As a outcomes of this truth we consult with at most $4 log n$ vertices in full, and that is equal to a working time of $O(log n)$.

In conclusion the ask works by dividing the input fragment into plenty of sub-segments for which the total sums are already precomputed and saved within the tree.
And if we discontinuance partitioning at any time when the ask fragment coincides with the vertex fragment, then we supreme want $O(log n)$ such segments, which provides the effectiveness of the Phase Tree.

Update queries

Now we are browsing out for to alter a chosen element within the array, as an example we are browsing out for to luxuriate in out the duty $a[i] = x$.
And now we possess got to rebuild the Phase Tree, such that it correspond to the fresh, modified array.

This ask is more straightforward than the sum ask.
Each and every level of a Phase Tree kinds a partition of the array.
As a outcomes of this truth a fraction $a[i]$ supreme contributes to 1 fragment from every level.
Thus supreme $O(log n)$ vertices would presumably presumably presumably presumably restful be up to this point.

It is miles easy to ascertain, that the change question would presumably presumably presumably presumably be utilized the usage of a recursive feature.
The feature will gain passed most continuously the most modern tree vertex, and it recursively calls itself with regarded as one of the most well-identified 2 little one vertices (the one who comprises $a[i]$ in its fragment), and after that recomputes its sum rate, identical the attract which it is performed within the comprise blueprint (that is for the explanation that sum of its two childhood).

In all places all over again right here is a visualization the usage of the identical array.
Right here we luxuriate in the change $a[2] = 3$.
The inexperienced vertices are the vertices that we consult with and change.

Implementation

The treasured consideration is pointers on the vogue to retailer the Phase Tree.
For unbelievable we are able to anecdote for a $text{Vertex}$ struct and gain objects, that retailer the boundaries of the fragment, its sum and additionally also pointers that can presumably presumably presumably its little one vertices.
Alternatively this requires storing a quantity of redundant puny print.
We’re going to remark a easy trick, to affect this broad extra ambiance winning.
We supreme retailer the sums in an array.
The sum of the muse vertex at index 1, the sums of its two little one vertices at indices 2 and 3, the sums of the childhood of these two vertices at indices 4 to 7, and plenty others.
It is miles easy to ascertain, that the left little regarded as one of a vertex at index $i$ is saved at index $2i$, and the supreme one at index $2i + 1$.

This simplifies the implementation loads.
We invent no longer have to retailer the vogue of the tree in memory.
It is miles printed implicitly.
We supreme want one array which comprises the sums of all segments.

As renowned earlier than, now we possess got to retailer at most $4n$ vertices.
It would presumably presumably presumably presumably presumably presumably be noteworthy less, however for comfort we continuously allocate an array of dimension $4n$.
There would possibly possibly be some facets within the sum array, that can presumably presumably presumably no longer correspond to any vertices within the accurate tree, however this doesn’t complicate the implementation.

So, we retailer the Phase Tree merely as an array $t[]$ with a dimension of 4 events the input dimension $n$:

int n, t[4*MAXN];

The blueprint for setting up the Phase Tree from a given array $a[]$ appears to be cherish this:
it is a ways a recursive feature with the parameters $a[]$ (the input array), $v$ (the index of most continuously the most modern vertex), and the boundaries $tl$ and $tr$ of most continuously the most modern fragment.
In the predominant program this feature would possibly possibly be called with the parameters of the muse vertex: $v = 1$, $tl = 0$, and $tr = n – 1$.

void comprise(int a[], int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = a[tl];
    } else {
        int tm = (tl + tr) / 2;
        comprise(a, v*2, tl, tm);
        comprise(a, v*2+1, tm+1, tr);
        t[v] = t[v*2] + t[v*2+1];
    }
}

Extra the feature for answering sum queries can even be a recursive feature, which receives as parameters puny print about most continuously the most modern vertex/fragment (i.e. the index $v$ and the boundaries $tl$ and $tr$) and likewise the puny print in regards to the boundaries of the ask, $l$ and $r$.
In screech to simplify the code, this feature continuously does two recursive calls, despite the indisputable fact that supreme one is crude – if that is so the superfluous recursive name will possess $l > r$, and this would presumably with out peril be caught the usage of an additional signal within the muse of the feature.

int sum(int v, int tl, int tr, int l, int r) {
    if (l > r) 
        return 0;
    if (l == tl && r == tr) {
        return t[v];
    }
    int tm = (tl + tr) / 2;
    return sum(v*2, tl, tm, l, min(r, tm))
           + sum(v*2+1, tm+1, tr, max(l, tm+1), r);
}

In the extinguish the change ask. The feature will even receive puny print about most continuously the most modern vertex/fragment, and additionally also the parameter of the change ask (i.e. the remark of the element and its fresh rate).

void change(int v, int tl, int tr, int pos, int new_val) {
    if (tl == tr) {
        t[v] = new_val;
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            change(v*2, tl, tm, pos, new_val);
        else
            change(v*2+1, tm+1, tr, pos, new_val);
        t[v] = t[v*2] + t[v*2+1];
    }
}

Memory efficient implementation

Most of us spend the implementation from the previous fragment. At the same time as you note on the array t you would peek that it follows the numbering of the tree nodes within the remark of a BFS traversal (level-remark traversal).
The spend of this traversal the kids of vertex $v$ are $2v$ and $2v + 1$ respectively.
Nonetheless if $n$ is now not any longer a energy of two, this vogue will skip some indices and leave some parts of the array t unused.
The memory consumption is particular by $4n$, despite the indisputable fact that a Phase Tree of an array of $n$ points requires simplest $2n - 1$ vertices.

However it absolutely would possibly possibly well be diminished.
We renumber the vertices of the tree within the remark of an Euler tour traversal (pre-remark traversal), and we write all these vertices subsequent to 1 one more.

Lets note at a vertex at index $v$, and let him be accountable for the segment $[l, r]$, and let $mid = dfrac{l + r}{2}$.
It is miles evident that the left little one would possibly possibly well possess the index $v + 1$.
The left little one is accountable for the segment $[l, mid]$, i.e. in total there would possibly possibly be $2 (mid - l + 1) - 1$ vertices within the left little one's subtree.
Thus we are able to compute the index of the ravishing little one of $v$. The index would possibly possibly be $v + 2 (mid - l + 1)$.
By this numbering we reach a low cost of the the largest memory to $2n$.

Evolved variations of Phase Bushes

A Phase Tree is a extraordinarily versatile data structure, and permits variations and extensions in a lot of a quantity of directions.
Let's try to categorize them beneath.

More advanced queries

It is miles also quite straightforward to trade the Phase Tree in a route, such that it computes different queries (e.g. computing the minimum / most in its set apart of the sum), however it absolutely also would possibly possibly well be very nontrivial.

Finding the most

Enable us to a little bit trade the condition of the difficulty described above: in its set apart of querying the sum, we can now affect most queries.

The tree would possibly possibly well possess precisely the identical structure as the tree described above.
We simplest prefer to trade the vogue $t[v]$ is computed within the $text{possess}$ and $text{change}$ capabilities.
$t[v]$ will now retailer the a lot of the corresponding segment.
And we also prefer to trade the calculation of the returned rate of the $text{sum}$ purpose (changing the summation by the most).

Needless to claim this difficulty would possibly possibly well be with out narrate modified into computing the minimum in its set apart of the most.

In desire to showing an implementation to this difficulty, the implementation would possibly possibly be given to a extra advanced model of this difficulty within the subsequent fragment.

Finding the most and the chance of times it appears to be

This job is terribly akin to the previous one.
In addition of discovering the most, we also prefer to search out the chance of occurrences of the most.

To solve this difficulty, we retailer a pair of numbers at every vertex within the tree:
Besides the most we also retailer the chance of occurrences of it within the corresponding segment.
Determining the trusty pair to retailer at $t[v]$ can quiet be done in constant time the usage of the figuring out of the pairs saved on the little one vertices.
Combining two such pairs must quiet be done in a separate purpose, since this is able to well be an operation that we will attain while constructing the tree, while answering most queries and while performing adjustments.

pair t[4*MAXN];

pair mix(pair a, pair b) {
    if (a.first > b.first) 
        return a;
    if (b.first > a.first)
        return b;
    return make_pair(a.first, a.2nd + b.2nd);
}

void comprise(int a[], int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = make_pair(a[tl], 1);
    } else {
        int tm = (tl + tr) / 2;
        comprise(a, v*2, tl, tm);
        comprise(a, v*2+1, tm+1, tr);
        t[v] = mix(t[v*2], t[v*2+1]);
    }
}

pair get_max(int v, int tl, int tr, int l, int r) {
    if (l > r)
        return make_pair(-INF, 0);
    if (l == tl && r == tr)
        return t[v];
    int tm = (tl + tr) / 2;
    return mix(get_max(v*2, tl, tm, l, min(r, tm)), 
                   get_max(v*2+1, tm+1, tr, max(l, tm+1), r));
}

void change(int v, int tl, int tr, int pos, int new_val) {
    if (tl == tr) {
        t[v] = make_pair(new_val, 1);
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            change(v*2, tl, tm, pos, new_val);
        else
            change(v*2+1, tm+1, tr, pos, new_val);
        t[v] = mix(t[v*2], t[v*2+1]);
    }
}

Compute the greatest overall divisor / least overall plenty of

In this difficulty we prefer to compute the GCD / LCM of all numbers of given ranges of the array.

This inviting variation of the Phase Tree would possibly possibly well be solved in only the identical device as the Phase Bushes we derived for sum / minimum / most queries:
it is enough to retailer the GCD / LCM of the corresponding vertex in every vertex of the tree.
Combining two vertices would possibly possibly well be done by computing the GCM / LCM of every vertices.

Counting the chance of zeros, browsing for the $ample$-th zero

In this difficulty we prefer to search out the chance of zeros in a given differ, and additionally assemble the index of the $ample$-th zero the usage of a 2nd purpose.

Again we possess got to trade the retailer values of the tree a chunk:
This time we can retailer the chance of zeros in every segment in $t[]$.
It is miles somewhat clear, the vogue to implement the $text{possess}$, $text{change}$ and $text{count_zero}$ capabilities, we are able to merely spend the strategies from the sum ask difficulty.
Thus we solved the first fragment of the difficulty.

Now we be taught the vogue to resolve the difficulty of discovering the $ample$-th zero within the array $a[]$.
To achieve this job, we can fall the Phase Tree, starting on the root vertex, and provocative at any time when to either the left or the ravishing little one, searching on which segment comprises the $ample$-th zero.
In screech to think to which little one we prefer to streak, it is enough to note on the chance of zeros appearing within the segment comparable to the left vertex.
If this precomputed depend is better or equal to $ample$, it is important to fall to the left little one, and otherwise descent to the ravishing little one.
See, if we chose the ravishing little one, we possess got to subtract the chance of zeros of the left little one from $ample$.

In the implementation we are able to address the actual case, $a[]$ containing decrease than $ample$ zeros, by returning -1.

int find_kth(int v, int tl, int tr, int ample) {
    if (ample > t[v])
        return -1;
    if (tl == tr)
        return tl;
    int tm = (tl + tr) / 2;
    if (t[v*2] >= okay)
        return find_kth(v*2, tl, tm, okay);
    else 
        return find_kth(v*2+1, tm+1, tr, okay - t[v*2]);
}

Having a note out to have an array prefix with a given quantity

The responsibility is as follows:
for a given rate $x$ now we possess got to all of a sudden receive smallest index $i$ such that the sum of the first $i$ facets of the array $a[]$ is better or equal to $x$ (assuming that the array $a[]$ supreme comprises non-destructive values).

This job would presumably presumably presumably presumably be solved the usage of binary search, computing the sum of the prefixes with the Phase Tree.
Alternatively this would presumably presumably presumably finish in a $O(log^2 n)$ resolution.

As a different we are able to remark the identical thought as within the out of date fragment, and receive the remark by descending the tree:
by complex at any time when to the left or the supreme, browsing on the sum of the left little one.
Thus discovering the acknowledge in $O(log n)$ time.

Having a note out to have the first element better than a given quantity

The responsibility is as follows:
for a given rate $x$ and a fluctuate $a[l dots r]$ receive the smallest $i$ within the fluctuate $a[l dots r]$, such that $a[i]$ is better than $x$.

This job would presumably presumably presumably presumably be solved the usage of binary search over max prefix queries with the Phase Tree.
Alternatively, this would presumably presumably presumably finish in a $O(log^2 n)$ resolution.

As a different, we are able to remark the identical thought as within the out of date sections, and receive the remark by descending the tree:
by complex at any time when to the left or the supreme, browsing on most continuously the most rate of the left little one.
Thus discovering the acknowledge in $O(log n)$ time.

int get_first(int v, int lv, int rv, int l, int r, int x) {
    if(lv > r || rv < l) return -1;
    if(l <= lv && rv <= r) {
        if(t[v] <= x) return -1;
        while(lv != rv) {
            int mid = lv + (rv-lv)/2;
            if(t[2*v] > x) {
                v = 2*v;
                rv = mid;
            }else {
                v = 2*v+1;
                lv = mid+1;
            }
        }
        return lv;
    }

    int mid = lv + (rv-lv)/2;
    int rs = get_first(2*v, lv, mid, l, r, x);
    if(rs != -1) return rs;
    return get_first(2*v+1, mid+1, rv, l ,r, x);
}

Finding subsegments with the maximal sum

Right here all over again we receive a fluctuate $a[l dots r]$ for every ask, this time now we possess got to have a subsegment $a[l^prime dots r^prime]$ such that $l le l^high$ and $r^high le r$ and the sum of the facets of this fragment is maximal.
As earlier than we are also browsing in repeat to alter teach teach individual facets of the array.
The facets of the array would presumably presumably presumably presumably be destructive, and the optimum subsegment would presumably presumably presumably presumably be empty (e.g. if all facets are destructive).

This expose is a non-trivial usage of a Phase Tree.
This time we are able to retailer four values for every vertex:
the sum of the fragment, most continuously the most prefix sum, most continuously the most suffix sum, and the sum of the maximal subsegment in it.
In other phrases for every fragment of the Phase Tree the acknowledge is already precomputed as effectively for the explanation that answers for segments touching the left and the supreme boundaries of the fragment.

comprise a tree with such puny print?
In all places all over again we compute it in a recursive vogue:
we first compute all four values for the left and the supreme little one, after which mix these to archive the four values for most continuously the most modern vertex.
Uncover the acknowledge for most continuously the most modern vertex is either:

  • the acknowledge of the left little one, that device that the optimum subsegment is totally positioned within the fragment of the left little one
  • the acknowledge of the supreme little one, that device that the optimum subsegment is totally positioned within the fragment of the supreme little one
  • the sum of most continuously the most suffix sum of the left little one and customarily the most prefix sum of the supreme little one, that device that the optimum subsegment intersects with each childhood.

As a outcomes of this truth the acknowledge to most continuously the most modern vertex is basically the all these three values.
Computing most continuously the most prefix / suffix sum is even extra easy.
Right here is the implementation of the $text{mix}$ feature, which receives supreme puny print from the left and trusty little one, and returns the puny print of most continuously the most modern vertex.

struct puny print {
    int sum, pref, suff, ans;
};

puny print mix(puny print l, puny print r) {
    puny print res;
    res.sum = l.sum + r.sum;
    res.pref = max(l.pref, l.sum + r.pref);
    res.suff = max(r.suff, r.sum + l.suff);
    res.ans = max(max(l.ans, r.ans), l.suff + r.pref);
    return res;
}

The usage of the $text{mix}$ feature it is a ways simple to comprise the Phase Tree.
We're going to implement it in simplest the identical blueprint as within the out of date implementations.
To initialize the leaf vertices, we additionally gain the auxiliary feature $text{make_data}$, that can presumably presumably presumably return a $text{puny print}$ object maintaining the puny print of a single rate.

puny print make_data(int val) {
    puny print res;
    res.sum = val;
    res.pref = res.suff = res.ans = max(0, val);
    return res;
}

void comprise(int a[], int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = make_data(a[tl]);
    } else {
        int tm = (tl + tr) / 2;
        comprise(a, v*2, tl, tm);
        comprise(a, v*2+1, tm+1, tr);
        t[v] = mix(t[v*2], t[v*2+1]);
    }
}

void change(int v, int tl, int tr, int pos, int new_val) {
    if (tl == tr) {
        t[v] = make_data(new_val);
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            change(v*2, tl, tm, pos, new_val);
        else
            change(v*2+1, tm+1, tr, pos, new_val);
        t[v] = mix(t[v*2], t[v*2+1]);
    }
}

It simplest remains, the vogue to compute the blueprint to a ask.
To answer to it, we streak down the tree as sooner than, breaking the ask into plenty of subsegments that coincide with the segments of the Phase Tree, and mix the answers in them trusty into a single solution for the ask.
Then it is going to quiet be clear, that the work is precisely the identical as within the easy Phase Tree, however in its set apart of summing / minimizing / maximizing the values, we spend the $text{mix}$ purpose.

data ask(int v, int tl, int tr, int l, int r) {
    if (l > r) 
        return make_data(0);
    if (l == tl && r == tr) 
        return t[v];
    int tm = (tl + tr) / 2;
    return mix(ask(v*2, tl, tm, l, min(r, tm)), 
                   ask(v*2+1, tm+1, tr, max(l, tm+1), r));
}

Saving the total subarrays in every vertex

Right here's a separate subsection that stands besides the others, because at every vertex of the Phase Tree we invent no longer retailer puny print in regards to the corresponding fragment in compressed dispute (sum, minimal, most, ...), however retailer all facets of the fragment.
Thus the muse of the Phase Tree will retailer all facets of the array, the left little one vertex will retailer the first half of of of the array, the supreme vertex the 2nd half of of, and plenty others.

In its absolute top utility of this vogue we retailer the facets in sorted snort.
In additional advanced variations the facets would possibly possibly well no longer be saved in lists, however extra improved puny print constructions (sets, maps, ...).
However all these capabilities possess the recurring ingredient, that every vertex requires linear memory (i.e. proportional to the scale of the corresponding fragment).

The treasured pure quiz, when pondering about these Phase Bushes, is determined memory consumption.
Intuitively this would presumably presumably presumably search cherish $O(n^2)$ memory, however it absolutely appears to be that the total tree will supreme want $O(n log n)$ memory.
Why is that this so?
A little merely, because every element of the array falls into $O(log n)$ segments (undergo in thoughts the finish of the tree is $O(log n)$).

So regardless of the hideous extravagance of this form of Phase Tree, it consumes supreme a chunk extra memory than the well-preferred Phase Tree.

Just a few well-preferred capabilities of this puny print constructing are described beneath.
It is miles mark noting the similarity of these Phase Bushes with 2D puny print constructions (if truth be taught right here is a 2D puny print constructing, however with moderately restricted capabilities).

Score the smallest quantity better or equal to a specified quantity. No modification queries.

We're browsing out for to acknowledge queries of the subsequent dispute:
for 3 given numbers $(l, r, x)$ now we possess got to have the minimal quantity within the fragment $a[l dots r]$ which is better than or equal to $x$.

We comprise a Phase Tree.
In every vertex we retailer a sorted checklist of all numbers going down within the corresponding fragment, cherish described above.
comprise this form of Phase Tree as effectively as imaginable?
As continuously we reach this expose recursively: let the lists of the left and trusty childhood already be constructed, and we are browsing out for to comprise the checklist for most continuously the most modern vertex.
From this ascertain the operation is now trivial and would presumably presumably presumably presumably be completed in linear time:
We supreme have to mix the 2 sorted lists into one, that can presumably presumably presumably be performed by iterating over them the usage of two pointers.
The C++ STL already has an implementation of this algorithm.

Because this constructing of the Phase Tree and the similarities to the merge kind algorithm, the puny print constructing can even be in most circumstances called "Merge Kind Tree".

vector t[4*MAXN];

void comprise(int a[], int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = vector(1, a[tl]);
    } else { 
        int tm = (tl + tr) / 2;
        comprise(a, v*2, tl, tm);
        comprise(a, v*2+1, tm+1, tr);
        merge(t[v*2].plot(), t[v*2].discontinuance(), t[v*2+1].plot(), t[v*2+1].discontinuance(),
              back_inserter(t[v]));
    }
}

We already know that the Phase Tree constructed on this blueprint will require $O(n log n)$ memory.
And as a final consequence of this implementation its constructing also takes $O(n log n)$ time, within the extinguish every checklist is constructed in linear time in admire to its dimension.

Now discover note of the acknowledge to the ask.
We're going to maneuver down the tree, cherish within the recurring Phase Tree, breaking our fragment $a[l dots r]$ into plenty of subsegments (into at most $O(log n)$ gadgets).
It is miles aesthetic that the acknowledge of the total acknowledge is the minimal of every of the subqueries.
So now we supreme have to cherish, pointers on the vogue to acknowledge a requirement on one such subsegment that corresponds with some vertex of the tree.

We're at some vertex of the Phase Tree and we are browsing out for to compute the acknowledge to the ask, i.e. receive the minimal quantity better that or equal to a given quantity $x$.
For the explanation that vertex comprises the checklist of facets in sorted snort, we are able to merely luxuriate in a binary search on this checklist and return the first quantity, better than or equal to $x$.

Thus the acknowledge to the ask in a single fragment of the tree takes $O(log n)$ time, and the total ask is processed in $O(log^2 n)$.

int ask(int v, int tl, int tr, int l, int r, int x) {
    if (l > r)
        return INF;
    if (l == tl && r == tr) {
        vector::iterator pos = lower_bound(t[v].plot(), t[v].discontinuance(), x);
        if (pos != t[v].discontinuance())
            return *pos;
        return INF;
    }
    int tm = (tl + tr) / 2;
    return min(ask(v*2, tl, tm, l, min(r, tm), x), 
               ask(v*2+1, tm+1, tr, max(l, tm+1), r, x));
}

The constant $text{INF}$ is equal to a pair broad quantity that is bigger than all numbers within the array.
Its usage blueprint, that there would presumably be no quantity better than or equal to $x$ within the fragment.
It has the that device of "there would presumably be no acknowledge within the given interval".

Score the smallest quantity better or equal to a specified quantity. With modification queries.

This job is comparable to the out of date.
The final reach has a downside, it venerable to be no longer imaginable to alter the array between answering queries.
Now we are browsing out for to luxuriate in out precisely this: a modification ask will elevate out the duty $a[i] = y$.

The resolution is comparable to the resolution of the out of date expose, however moderately than lists at every vertex of the Phase Tree, we are able to retailer a balanced checklist that lets you all of a sudden see numbers, delete numbers, and insert fresh numbers.
For the explanation that array can admire a quantity repeated, the optimum desire is the puny print constructing $text{multiset}$.

The enchancment of this form of Phase Tree is performed in moderately broad the identical blueprint as within the out of date expose, supreme now now we possess got to mix $text{multiset}$s and never sorted lists.
This ends in a constructing time of $O(n log^2 n)$ (in venerable merging two crimson-shadowy bushes would presumably presumably presumably presumably be performed in linear time, on the other hand the C++ STL doesn't screech this time complexity).

The $text{ask}$ feature can even be nearly identical, supreme now the $text{lower_bound}$ feature of the $text{multiset}$ feature must be called in its set apart ($text{std::lower_bound}$ supreme works in $O(log n)$ time if susceptible with random-derive entry to iterators).

In the extinguish the modification question.
To job it, we have to maneuver down the tree, and alter all $text{multiset}$ from the corresponding segments that correct admire the effected element.
We merely delete the old-fashioned rate of this element (however supreme one occurrence), and insert the fresh rate.

void change(int v, int tl, int tr, int pos, int new_val) {
    t[v].erase(t[v].receive(a[pos]));
    t[v].insert(new_val);
    if (tl != tr) {
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            change(v*2, tl, tm, pos, new_val);
        else
            change(v*2+1, tm+1, tr, pos, new_val);
    } else {
        a[pos] = new_val;
    }
}

Processing of this alteration ask also takes $O(log^2 n)$ time.

Score the smallest quantity better or equal to a specified quantity. Acceleration with "fractional cascading".

We now possess the identical difficulty statement, we prefer to search out the minimal quantity better than or equal to $x$ in a segment, however this time in $O(log n)$ time.
We're going to give a discover to the time complexity the usage of the blueprint "fractional cascading".

Fractional cascading is a straightforward blueprint that lets you give a discover to the running time of plenty of binary searches, which would possibly possibly be performed on the identical time.
Our previous blueprint to the quest ask became, that we divide the duty into plenty of subtasks, every of which is solved with a binary search.
Fractional cascading lets you interchange all of these binary searches with a single one.

The simplest and most evident instance of fractional cascading is the next difficulty:
there are $ample$ sorted lists of numbers, and we have to assemble in every checklist the first quantity better than or equal to the given quantity.

In desire to performing a binary see every checklist, we would merge all lists into one mountainous sorted checklist.
Furthermore for every ingredient $y$ we retailer a listing of outcomes of browsing for $y$ in every of the $ample$ lists.
On account of this fact if we prefer to search out the smallest quantity better than or equal to $x$, we correct prefer to discover one single binary search, and from the checklist of indices we are able to resolve the smallest quantity in every checklist.
This device on the other hand requires $O(n cdot ample)$ ($n$ is the length of the blended lists), which would possibly possibly well be quite inefficient.

Fractional cascading reduces this memory complexity to $O(n)$ memory, by rising from the $ample$ input lists $ample$ fresh lists, in which every checklist comprises the corresponding checklist and additionally also every 2nd ingredient of the next fresh checklist.
The spend of this structure it is simplest most important to retailer two indices, the index of the ingredient within the novel checklist, and the index of the ingredient within the next fresh checklist.
So this vogue simplest uses $O(n)$ memory, and quiet can solution the queries the usage of a single binary search.

However for our application we attain no longer want the total energy of fractional cascading.
In our Phase Tree a vertex will have the sorted checklist of all points that occur in either the left or the ravishing subtrees (admire within the Merge Form Tree).
Furthermore to this sorted checklist, we retailer two positions for every ingredient.
For a element $y$ we retailer the smallest index $i$, such that the $i$th ingredient within the sorted checklist of the left little one is better or equal to $y$.
And we retailer the smallest index $j$, such that the $j$th ingredient within the sorted checklist of the ravishing little one is better or equal to $y$.
These values would possibly possibly well be computed in parallel to the merging step when we possess the tree.

How does this bustle up the queries?

Take into anecdote, within the recurring solution we did a binary search in ever node.
However with this alteration, we are able to luxuriate in a ways from all except for one.

To answer to a ask, we merely to a binary search within the root node.
This provides as the smallest ingredient $y ge x$ on your complete array, however it absolutely also provides us two positions.
The index of the smallest ingredient better or equal $x$ within the left subtree, and the index of the smallest ingredient $y$ within the ravishing subtree. See that $ge y$ is the identical as $ge x$, since our array doesn't have any points between $x$ and $y$.
In the recurring Merge Form Tree solution we would compute these indices through binary search, however with the attend of the precomputed values we are able to correct note them up in $O(1)$.
And we are able to repeat that unless we visited all nodes that cowl our ask interval.

To summarize, as typical we touch $O(log n)$ nodes within the future of a ask. In the root node we attain a binary search, and in all other nodes we simplest attain constant work.
This implies the complexity for answering a ask is $O(log n)$.

However gape, that this uses thrice extra memory than a recurring Merge Form Tree, which already uses a quantity of memory ($O(n log n)$).

It is miles easy to note this blueprint to an area, that doesn't require any modification queries.
The 2 positions are correct integers and can with out narrate be computed by counting when merging the two sorted sequences.

It it quiet doubtless to also enable modification queries, however that complicates your complete code.
In desire to integers, that you must retailer the sorted array as multiset, and in its set apart of indices that you must retailer iterators.
And that you must work very fastidiously, so as that you increment or decrement the trusty iterators within the future of a modification ask.

Diversified doubtless variations

This kind implies an complete fresh class of doubtless capabilities.
In desire to storing a $text{vector}$ or a $text{multiset}$ in every vertex, other data constructions would possibly possibly well be venerable:
other Phase Bushes (a chunk discussed in Generalization to elevated dimensions), Fenwick Bushes, Cartesian trees, and plenty others.

Fluctuate updates (Indolent Propagation)

All complications within the above sections discussed modification queries that simplest effected a single ingredient of the array every.
Nonetheless the Phase Tree permits applying modification queries to a full segment of contiguous points, and discover the ask within the identical time $O(log n)$.

Addition on segments

We open by pondering complications of the greatest kind: the modification ask must quiet add a quantity $x$ to all numbers within the segment $a[l dots r]$.
The 2nd ask, that we are supposed to answer, asked merely for the associated rate of $a[i]$.

To electrify the addition ask efficient, we retailer at every vertex within the Phase Tree what number of we must quiet add to all numbers within the corresponding segment.
Let's keep in mind, if the ask "add 3 to the total array $a[0 dots n-1]$" comes, then we space the amount 3 within the root of the tree.
In recurring we possess got to space this quantity plenty of to plenty of segments, which sort a partition of the ask segment.
Thus we invent no longer prefer to trade all $O(n)$ values, however simplest $O(log n)$ many.

If now there comes a ask that asks the most modern rate of a teach array entry, it is enough to streak down the tree and add up all values chanced on along the vogue.

void possess(int a[], int v, int tl, int tr) {
    if (tl == tr) {
        t[v] = a[tl];
    } else {
        int tm = (tl + tr) / 2;
        possess(a, v*2, tl, tm);
        possess(a, v*2+1, tm+1, tr);
        t[v] = 0;
    }
}

void change(int v, int tl, int tr, int l, int r, int add) {
    if (l > r)
        return;
    if (l == tl && r == tr) {
        t[v] += add;
    } else {
        int tm = (tl + tr) / 2;
        change(v*2, tl, tm, l, min(r, tm), add);
        change(v*2+1, tm+1, tr, max(l, tm+1), r, add);
    }
}

int derive(int v, int tl, int tr, int pos) {
    if (tl == tr)
        return t[v];
    int tm = (tl + tr) / 2;
    if (pos <= tm)
        return t[v] + gain(v*2, tl, tm, pos);
    else
        return t[v] + gain(v*2+1, tm+1, tr, pos);
}

Project on segments

Command now that the modification ask asks to set apart every ingredient of a determined segment $a[l dots r]$ to some rate $p$.
As a 2nd ask we can all over again possess in thoughts discovering out the associated rate of the array $a[i]$.

To discover this alteration ask on an complete segment, you've got to retailer at every vertex of the Phase Tree whether or no longer the corresponding segment is covered completely with the identical rate or no longer.
This permits us to affect a "lazy" change:
in its set apart of altering all segments within the tree that cowl the ask segment, we simplest trade some, and leave others unchanged.
A marked vertex will imply, that every ingredient of the corresponding segment is assigned to that rate, and in truth also your complete subtree must quiet simplest have this rate.
In a sense we are lazy and delay writing the fresh rate to all these vertices.
We're going to achieve this late job later, if this is important.

So after the modification ask is completed, some parts of the tree become inappropriate - some adjustments stay unfulfilled in it.

Let's keep in mind if a modification ask "set apart a quantity to the total array $a[0 dots n-1]$" gets completed, within the Phase Tree simplest a single trade is made - the amount is positioned within the root of the tree and this vertex gets marked.
The final segments stay unchanged, though essentially the amount must quiet be positioned within the total tree.

Command now that the 2nd modification ask says, that the first half of of the array $a[0 dots n/2]$ must quiet be assigned with every other quantity.
To route of this ask we have to set apart every ingredient within the total left little one of the important root vertex with that quantity.
However sooner than we attain this, we have to first kind out the root vertex first.
The subtlety right here is that the ravishing half of of the array must quiet quiet be assigned to the associated rate of the first ask, and for the time being there's now not any info for the ravishing half of saved.

The blueprint to resolve this is to push the figuring out of the root to its kids, i.e. if the root of the tree became assigned with any quantity, then we set apart the left and the ravishing little one vertices with this quantity and prefer the mark of the root.
After that, we are able to set apart the left little one with the fresh rate, with out loosing any most important info.

Summarizing we gain:
for any queries (a modification or discovering out ask) within the future of the descent along the tree we must quiet always push info from the most modern vertex into each of its kids.
We're going to clutch this in such a technique, that when we descent the tree we note delayed adjustments, however precisely as noteworthy as most important (so no longer to degrade the complexity of $O(log n)$.

For the implementation we prefer to affect a $text{push}$ purpose, that would possibly possibly well merely receive the most modern vertex, and it will push the figuring out for its vertex to each its kids.
We're going to name this purpose on the starting of the ask capabilities (however we is now not any longer going to name it from the leaves, because there's now not any prefer to push info from them from now on).

void push(int v) {
    if (marked[v]) {
        t[v*2] = t[v*2+1] = t[v];
        marked[v*2] = marked[v*2+1] = trusty;
        marked[v] = false;
    }
}

void change(int v, int tl, int tr, int l, int r, int new_val) {
    if (l > r) 
        return;
    if (l == tl && tr == r) {
        t[v] = new_val;
        marked[v] = applicable;
    } else {
        push(v);
        int tm = (tl + tr) / 2;
        change(v*2, tl, tm, l, min(r, tm), new_val);
        change(v*2+1, tm+1, tr, max(l, tm+1), r, new_val);
    }
}

int derive(int v, int tl, int tr, int pos) {
    if (tl == tr) {
        return t[v];
    }
    push(v);
    int tm = (tl + tr) / 2;
    if (pos <= tm) 
        return gain(v*2, tl, tm, pos);
    else
        return gain(v*2+1, tm+1, tr, pos);
}

See: the aim $text{gain}$ can even be applied in a recurring device:
attain no longer affect delayed updates, however without delay return the associated rate $t[v]$ if $marked[v]$ is correct.

Adding on segments, querying for optimum

Now the modification ask is to be able to add a quantity to all points in a form, and the discovering out ask is to search out the most in a form.

So for every vertex of the Phase Tree we possess got to retailer the a lot of the corresponding subsegment.
The inviting fragment is the vogue to recompute these values within the future of a modification question.

For this motive we luxuriate in retailer an additional rate for every vertex.
In this rate we retailer the addends we haven't propagated to the little one vertices.
Before traversing to a chunk one vertex, we name $text{push}$ and propagate the associated rate to each kids.
We now prefer to achieve this in each the $text{change}$ purpose and the $text{ask}$ purpose.

void push(int v) {
    t[v*2] += lazy[v];
    lazy[v*2] += lazy[v];
    t[v*2+1] += lazy[v];
    lazy[v*2+1] += lazy[v];
    lazy[v] = 0;
}

void change(int v, int tl, int tr, int l, int r, int addend) {
    if (l > r) 
        return;
    if (l == tl && tr == r) {
        t[v] += addend;
        sluggish[v] += addend;
    } else {
        push(v);
        int tm = (tl + tr) / 2;
        change(v*2, tl, tm, l, min(r, tm), addend);
        change(v*2+1, tm+1, tr, max(l, tm+1), r, addend);
        t[v] = max(t[v*2], t[v*2+1]);
    }
}

int ask(int v, int tl, int tr, int l, int r) {
    if (l > r)
        return -INF;
    if (l <= tl && tr <= r)
        return t[v];
    push(v);
    int tm = (tl + tr) / 2;
    return max(ask(v*2, tl, tm, l, min(r, tm)), 
               ask(v*2+1, tm+1, tr, max(l, tm+1), r));
}

Generalization to elevated dimensions

A Phase Tree would possibly possibly well be generalized quite natural to elevated dimensions.
If within the one-dimensional case we chop up the indices of the array into segments, then within the two-dimensional we affect a traditional Phase Tree with admire to the first indices, and for every segment we possess a traditional Phase Tree with admire to the 2nd indices.

Easy 2D Phase Tree

A matrix $a[0 dots n-1, 0 dots m-1]$ is given, and we possess got to search out the sum (or minimum/most) on some submatrix $a[x_1 dots x_2, y_1 dots y_2]$, as well to discover adjustments of particular individual matrix points (i.e. queries of the kind $a[x][y] = p$).

So we possess a 2D Phase Tree: first the Phase Tree the usage of the first coordinate ($x$), then the 2nd ($y$).

To electrify the constructing route of additional understandable, you would fail to recollect for a while that the matrix is 2-dimensional, and simplest leave the first coordinate.
We're going to gain a traditional one-dimensional Phase Tree the usage of simplest the first coordinate.
However in its set apart of storing a quantity in a segment, be retailer a full Phase Tree:
i.e. at this 2nd we keep in mind that we even possess a 2nd coordinate; however because at this 2nd the first coordinate is already fixed to some interval $[l dots r]$, we finally work with such a strip $a[l dots r, 0 dots m-1]$ and for it we possess a Phase Tree.

Right here is the implementation of the constructing of a 2D Phase Tree.
It finally represents two separate blocks:
the constructing of a Phase Tree along the $x$ coordinate ($text{possess}_x$), and the $y$ coordinate ($text{possess}_y$).
For the leaf nodes in $text{possess}_y$ we possess got to separate two circumstances:
when the most modern segment of the first coordinate $[tlx dots trx]$ has length 1, and when it has a length better than one. In the first case, we correct discover the corresponding rate from the matrix, and within the 2nd case we are able to mix the values of two Phase Bushes from the left and the ravishing son within the coordinate $x$.

void build_y(int vx, int lx, int rx, int vy, int ly, int ry) {
    if (ly == ry) {
        if (lx == rx)
            t[vx][vy] = a[lx][ly];
        else
            t[vx][vy] = t[vx*2][vy] + t[vx*2+1][vy];
    } else {
        int my = (ly + ry) / 2;
        build_y(vx, lx, rx, vy*2, ly, my);
        build_y(vx, lx, rx, vy*2+1, my+1, ry);
        t[vx][vy] = t[vx][vy*2] + t[vx][vy*2+1];
    }
}

void build_x(int vx, int lx, int rx) {
    if (lx != rx) {
        int mx = (lx + rx) / 2;
        build_x(vx*2, lx, mx);
        build_x(vx*2+1, mx+1, rx);
    }
    build_y(vx, lx, rx, 1, 0, m-1);
}

This kind of Phase Tree quiet uses a linear quantity of memory, however with a bigger constant: $16 n m$.
It is miles clear that the described device $text{possess}_x$ also works in linear time.

Now we flip to processing of queries. We're going to blueprint to the two-dimensional ask the usage of the identical precept:
first destroy the ask on the first coordinate, after which for every reached vertex, we name the corresponding Phase Tree of the 2nd coordinate.

int sum_y(int vx, int vy, int tly, int try_, int ly, int ry) {
    if (ly > ry) 
        return 0;
    if (ly == tly && try_ == ry)
        return t[vx][vy];
    int tmy = (tly + try_) / 2;
    return sum_y(vx, vy*2, tly, tmy, ly, min(ry, tmy))
         + sum_y(vx, vy*2+1, tmy+1, try_, max(ly, tmy+1), ry);
}

int sum_x(int vx, int tlx, int trx, int lx, int rx, int ly, int ry) {
    if (lx > rx)
        return 0;
    if (lx == tlx && trx == rx)
        return sum_y(vx, 1, 0, m-1, ly, ry);
    int tmx = (tlx + trx) / 2;
    return sum_x(vx*2, tlx, tmx, lx, min(rx, tmx), ly, ry)
         + sum_x(vx*2+1, tmx+1, trx, max(lx, tmx+1), rx, ly, ry);
}

This chance works in $O(log n log m)$ time, since it first descends the free within the first coordinate, and for every traversed vertex within the tree it makes a requirement within the corresponding Phase Tree along the 2nd coordinate.

In the extinguish now we possess got in thoughts the modification ask.
We're browsing out for to be taught to alter the Phase Tree basically basically based largely completely completely on the swap within the associated rate of some element $a[x][y] = p$.
It is miles aesthetic, that the adjustments will happen supreme in these vertices of the first Phase Tree that display cowl cowl the coordinate $x$ (and such would possibly possibly be $O(log n)$), and for Phase Bushes akin to them the adjustments will supreme happens at these vertices that covers the coordinate $y$ (and such would possibly possibly be $O(log m)$).
As a outcomes of this truth the implementation would possibly possibly be no longer very diversified dispute the one-dimensional case, supreme now we first fall the first coordinate, after which the 2nd.

void update_y(int vx, int lx, int rx, int vy, int ly, int ry, int x, int y, int new_val) {
    if (ly == ry) {
        if (lx == rx)
            t[vx][vy] = new_val;
        else
            t[vx][vy] = t[vx*2][vy] + t[vx*2+1][vy];
    } else {
        int my = (ly + ry) / 2;
        if (y <= my)
            update_y(vx, lx, rx, vy*2, ly, my, x, y, new_val);
        else
            update_y(vx, lx, rx, vy*2+1, my+1, ry, x, y, new_val);
        t[vx][vy] = t[vx][vy*2] + t[vx][vy*2+1];
    }
}

void update_x(int vx, int lx, int rx, int x, int y, int new_val) {
    if (lx != rx) {
        int mx = (lx + rx) / 2;
        if (x <= mx)
            update_x(vx*2, lx, mx, x, y, new_val);
        else
            update_x(vx*2+1, mx+1, rx, x, y, new_val);
    }
    update_y(vx, lx, rx, 1, 0, m-1, x, y, new_val);
}

Compression of 2D Phase Tree

Let the difficulty be the next: there are $n$ points on the aircraft given by their coordinates $(x_i, y_i)$ and queries of the kind "depend the chance of points lying within the rectangle $((x_1, y_1), (x_2, y_2))$".
It is miles clear that within the case of such an area it turns into unreasonably wasteful to gain a two-dimensional Phase Tree with $O(n^2)$ points.
Most on this memory would possibly possibly be wasted, since every single point can simplest gain into $O(log n)$ segments of the tree along the first coordinate, and subsequently the overall "priceless" dimension of all tree segments on the 2nd coordinate is $O(n log n)$.

So we proceed as follows:
at every vertex of the Phase Tree with admire to the first coordinate we retailer a Phase Tree constructed simplest by these 2nd coordinates that occur within the most modern segment of the first coordinates.
In other phrases, when constructing a Phase Tree interior some vertex with index $vx$ and the boundaries $tlx$ and $trx$, we simplest possess in thoughts these points that fall into this interval $x in [tlx, trx]$, and possess a Phase Tree correct the usage of them.

Thus we can reach that every Phase Tree on the 2nd coordinate will choose precisely as noteworthy memory because it is going to quiet.
Which potential, the overall quantity of memory will decrease to $O(n log n)$.
We quiet can solution the queries in $O(log^2 n)$ time, we correct prefer to affect a binary search on the 2nd coordinate, however this is able to well no longer irritate the complexity.

However modification queries would possibly possibly be no longer doable with this structure:
essentially if a brand fresh point appears to be, we possess got to be able to add a brand fresh ingredient within the course of some Phase Tree along the 2nd coordinate, which would possibly possibly't be effectively done.

In conclusion we display cowl that the two-dimensional Phase Tree diminished in dimension within the described device turns into practically comparable to the modification of the one-dimensional Phase Tree (peek Saving your complete subarrays in every vertex).
In teach the two-dimensional Phase Tree is correct a determined case of storing a subarray in every vertex of the tree.
It follows, that in case you gave to desert a two-dimensional Phase Tree as a result of impossibility of executing a ask, it is a ways life like to examine to interchange the nested Phase Tree with some extra noteworthy data structure, as an example a Cartesian tree.

Preserving the historic past of its values (Chronic Phase Tree)

A persistent data structure is a data structure that remembers it previous dispute for every modification.
This permits to gain trusty of entry to any model of this data structure that keenness us and reach a ask on it.

Phase Tree is a data structure that can even be turned trusty into a persistent data structure efficiently (each in time and memory consumption).
We would favor to luxuriate in a ways from copying your complete tree sooner than every modification, and we invent no longer prefer to free the $O(log n)$ time habits for answering differ queries.

Of route, any trade question within the Phase Tree ends in a trade within the data of simplest $O(log n)$ vertices along the fade ranging from the root.
So if we retailer the Phase Tree the usage of pointers (i.e. a vertex retail outlets pointers to the left and the ravishing little one vertices), then when performing the modification ask, we merely prefer to attain fresh vertices in its set apart of altering the readily available vertices.
Vertices which would possibly possibly be no longer struggling from the modification ask can quiet be venerable by pointing the pointers to the frail vertices.
Thus for a modification ask $O(log n)$ fresh vertices would possibly possibly be created, at the side of a brand fresh root vertex of the Phase Tree, and your complete previous model of the tree rooted on the frail root vertex will stay unchanged.

Let's give an instance implementation for the greatest Phase Tree: when there's simplest a ask inquiring for sums, and modification queries of single points.

struct Vertex {
    Vertex *l, *r;
    int sum;

    Vertex(int val) : l(nullptr), r(nullptr), sum(val) {}
    Vertex(Vertex *l, Vertex *r) : l(l), r(r), sum(0) {
        if (l) sum += l->sum;
        if (r) sum += r->sum;
    }
};

Vertexcomprise(int a[], int tl, int tr) {
    if (tl == tr)
        return fresh Vertex(a[tl]);
    int tm = (tl + tr) / 2;
    return fresh Vertex(comprise(a, tl, tm), comprise(a, tm+1, tr));
}

int get_sum(Vertexv, int tl, int tr, int l, int r) {
    if (l > r)
        return 0;
    if (l == tl && tr == r)
        return v->sum;
    int tm = (tl + tr) / 2;
    return get_sum(v->l, tl, tm, l, min(r, tm))
         + get_sum(v->r, tm+1, tr, max(l, tm+1), r);
}

Vertexupdate(Vertexv, int tl, int tr, int pos, int new_val) {
    if (tl == tr)
        return fresh Vertex(new_val);
    int tm = (tl + tr) / 2;
    if (pos <= tm)
        return new Vertex(update(v->l, tl, tm, pos, new_val), v->r);
    else
        return fresh Vertex(v->l, change(v->r, tm+1, tr, pos, new_val));
}

For every modification of the Phase Tree we are able to receive a brand fresh root vertex.
To all of a sudden soar between two diversified variations of the Phase Tree, now we possess got to retailer this roots in an array.
To electrify remark of a specific model of the Phase Tree we merely name the ask the usage of the accurate root vertex.

With the reach described above nearly any Phase Tree would presumably presumably presumably presumably be grew to become trusty trusty into a persistent puny print constructing.

Finding the $okay$-th smallest quantity in a fluctuate

This time now we possess got to acknowledge queries of the dispute "What's the $okay$-th smallest element within the fluctuate $a[l dots r]$.
This ask would presumably presumably presumably presumably be answered the usage of a binary search and a Merge Kind Tree, on the other hand the time complexity for a single ask would possibly possibly well per chance be $O(log^3 n)$.
We're going to achieve the identical job the usage of a persistent Phase Tree in $O(log n)$.

First we are able to focal point on a resolution for a extra easy expose:
We're going to supreme discover note of arrays thru which the facets are accelerate by $0 los angeles19459069] lt n$.
And we supreme are browsing out for to have the $okay$-th smallest element in some prefix of the array $a$.
This would presumably once in a while be very easy to extent the developed strategies later for no longer restricted arrays and never restricted fluctuate queries.

We're going to remark a Phase Tree that counts all exhibiting numbers, i.e. within the Phase Tree we are able to retailer the histogram of the array.
So the leaf vertices will retailer how in most circumstances the values $0$, $1$, $dots$, $n-1$ will seem within the array, and the opposite vertices retailer what number of numbers in some fluctuate are within the array.
In other phrases we gain a recurring Phase Tree with sum queries over the histogram of the array.
However moderately than rising all $n$ Phase Bushes for every imaginable prefix, we are able to gain one persistent one, that can correct admire the identical puny print.
We're going to plot with an empty Phase Tree (all counts would possibly possibly be $0$), and add the facets $a[0]$, $a[1]$, $dots$, $a[n-1]$ one after every other.
For every modification we are able to receive a brand fresh root vertex, let's name $root_i$ the muse of the Phase Tree after inserting the first $i$ facets of the array $a$.
The Phase Tree rooted at $root_i$ will correct admire the histogram of the prefix $a[0 dots i-1]$.
The usage of this Phase Tree we are able to have in $O(log n)$ time the remark of the $okay$-th element the usage of the identical device discussed in Counting the want of zeros, procuring for the $okay$-th zero.

Now to the no longer-restricted model of the expose.

First for the restriction on the array:
We're going to if truth be taught become any array to such an array by index compression.
The smallest element within the array will will gain assigned the associated rate 0, the 2nd smallest the associated rate 1, and plenty others.
It is miles easy to generate note up tables (e.g. the usage of $text{blueprint}$), that convert a rate to its index and vice versa in $O(log n)$ time.

Now to the queries restriction:
moderately than supreme performing these queries over a prefix of $a$, we are browsing out for to remark any arbitrary segments $a[l dots r]$.
Right here we desire a Phase Tree that represents the histogram of the facets within the fluctuate $a[l dots r]$.
It is miles easy to ascertain that this form of Phase Tree is applicable the variation between the Phase Tree rooted at $root_{r+1}$ and the Phase Tree rooted at $root_l$, i.e. every vertex within the $[l dots r]$ Phase Tree would presumably presumably presumably presumably be computed with the vertex of the $root_{r+1}$ tree minus the vertex of the $root_l$ tree.
In the implementation of the $text{get_kth}$ feature this would presumably be handled by passing two vertex pointer and computing the depend/sum of most continuously the most modern fragment as distinction of the 2 counts/sums of the vertices.

Implicit fragment tree

Beforehand, we view to be circumstances when now we possess got the potential to comprise the recurring fragment tree. However what to luxuriate in out if the recurring dimension is stuffed with some default element, however its dimension doesn't screech their deepest praises you the vogue to utterly comprise up to it in approach?

We're going to medication this expose by no longer explicitly rising a fraction tree. In the muse, we are able to gain supreme the muse, and we are able to gain the opposite vertexes supreme when we desire them.
In this case, we are able to remark the implementation on pointers(earlier than going to the vertex childhood, ascertain whether or no longer or no longer they're created, and if no longer, gain them).
Each and every ask has restful supreme the complexity $O(log n)$, which is sufficiently puny for heaps of remark-circumstances (e.g. $log_2 10^9 approx 30$).

In this implementation now we possess got two queries, adding a rate to a remark (within the muse all values are $0$), and computing the sum of all values in a fluctuate.
Vertex(0, n) most continuously is the muse vertex of the implicit tree.

struct Vertex {
    int left, trusty;
    int sum = 0;
    Vertex *left_child = nullptr, *right_child = nullptr;

    Vertex(int lb, int rb) {
        left = lb;
        trusty = rb;
    }

    void lengthen() {
        if (!left_child && left + 1 < ravishing) {
            int t = (left + ravishing) / 2;
            left_child = fresh Vertex(left, t);
            right_child = fresh Vertex(t, ravishing);
        }
    }

    void add(int ample, int x) {
        delay();
        sum += x;
        if (left_child) {
            if (ample < left_child->ravishing)
                left_child->add(okay, x);
            else
                right_child->add(okay, x);
        }
    }

    int get_sum(int lq, int rq) {
        if (lq <= left && ravishing <= rq)
            return sum;
        if (max(left, lq) >= min(ravishing, rq))
            return 0;
        delay();
        return left_child->get_sum(lq, rq) + right_child->get_sum(lq, rq);
    }
};

Obviously this thought would presumably presumably presumably presumably be extended in a quantity of diversified ways. E.g. by adding abet for fluctuate updates by job of sluggish propagation.

Command Points

Lire plus

Leave a Comment

Recent Posts

Gallery-dl – obtain photos from several image web web hosting sites
Watercooled Canon R5 with unlocked unlimited 8K recording
On Glaciers, balls of mud and moss incessantly called ‘glacier mice’ impact a residence (2012)
Instruct HN: liblgpp – an extensible stack essentially based VM for interpreters in C++
Why did it employ nine hours to run 130 miles in our unique electrical Porsche?

Recent Posts

Gallery-dl – obtain photos from several image web web hosting sites
Watercooled Canon R5 with unlocked unlimited 8K recording
On Glaciers, balls of mud and moss incessantly called ‘glacier mice’ impact a residence (2012)
Instruct HN: liblgpp – an extensible stack essentially based VM for interpreters in C++
Why did it employ nine hours to run 130 miles in our unique electrical Porsche?
en_USEnglish
fr_FRFrench en_USEnglish