You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/data-structures/segment-tree.md
+8-4Lines changed: 8 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -103,6 +103,7 @@ Previously, update function was called to update only a single value in array. P
103
103
104
104
### Lazy Propogation Algorithm
105
105
We need a structure that can perform following operations on an array $[1,N]$.
106
+
106
107
- Add inc to all elements in the given range $[l, r]$.
107
108
- Return the sum of all elements in the given range $[l, r]$.
108
109
@@ -118,6 +119,7 @@ Trick is to be lazy i.e, do work only when needed. Do the updates only when you
118
119
Let’s be <i>lazy</i> as told, when we need to update an interval, we will update a node and mark its children that it needs to be updated and update them when needed. For this we need an array $lazy[]$ of the same size as that of segment tree. Initially all the elements of the $lazy[]$ array will be $0$ representing that there is no pending update. If there is non-zero element $lazy[k]$ then this element needs to update node k in the segment tree before making any query operation, then $lazy[2\cdot k]$ and $lazy[2 \cdot k + 1]$ must be also updated correspondingly.
119
120
120
121
To update an interval we will keep 3 things in mind.
122
+
121
123
- If current segment tree node has any pending update, then first add that pending update to current node and push the update to it’s children.
122
124
- If the interval represented by current node lies completely in the interval to update, then update the current node and update the $lazy[]$ array for children nodes.
123
125
- If the interval represented by current node overlaps with the interval to update, then update the nodes as the earlier update function.
@@ -202,6 +204,7 @@ Notice that the only difference with the regular query function is pushing the l
202
204
203
205
## Binary Search on Segment Tree
204
206
Assume we have an array A that contains elements between 1 and $M$. We have to perform 2 kinds of operations.
207
+
205
208
- Change the value of the element in given index i by x.
206
209
- Return the value of the kth element on the array when sorted.
207
210
@@ -240,8 +243,9 @@ This is of course, slow. Let’s use segment tree’s to improve it. First we wi
240
243
<figuremarkdown = "span">
241
244
{ width="100%" }
242
245
<figcaption>Segment Tree After First Update</figcaption>
246
+
</figure>
243
247
244
-
```c++
248
+
```cpp
245
249
voidupdate(int i, int x) {
246
250
update(1, 1, M, A[i], --F[A[i]]); // Decrement frequency of old value
247
251
A[i] = x; // Update A[i] to new value
@@ -263,15 +267,15 @@ int query(int k) {
263
267
264
268
If you look at the code above you can notice that each update takes $\mathcal{O}(\log M)$ time and each query takes $\mathcal{O}(\log^{2} M)$ time, but we can do better.
265
269
266
-
###How To Speed Up?
270
+
###How To Speed Up?
267
271
If you look at the segment tree solution on preceding subsection you can see that queries are performed in $\mathcal{O}(\log^{2} M)$ time. We can make is faster, actually we can reduce the time complexity to $\mathcal{O}(\log M)$ which is same with the time complexity for updates. We will do the binary search when we are traversing the segment tree. We first will start from the root and look at its left child’s sum value, if this value is greater than k, this means our answer is somewhere in the left child’s subtree. Otherwise it is somewhere in the right child’s subtree. We will follow a path using this rule until we reach a leaf, then this will be our answer. Since we just traversed $\mathcal{O}(\log M)$ nodes (one node at each level), time complexity will be $\mathcal{O}(\log M)$. Look at the code below for better understanding.
268
272
269
273
<figure markdown = "span">
270
274
{ width="100%" }
271
275
<figcaption>Solution of First Query</figcaption>
272
276
</figure>
273
277
274
-
```c++
278
+
```cpp
275
279
void update(int i, int x) {
276
280
update(1, 1, M, A[i], --F[A[i]]); // Decrement frequency of old value
277
281
A[i] = x; // Update A[i] to new value
@@ -289,4 +293,4 @@ int query(int node, int start, int end, int k) {
289
293
int query(int k) {
290
294
return query(1, 1, M, k); // Public interface for querying
0 commit comments