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: Segment Tree/LazyPropagation/README.markdown
+70-31Lines changed: 70 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -71,6 +71,7 @@ public func query(leftBound: Int, rightBound: Int) -> T {
71
71
Position ① means that the left bound of current query interval is on the right of this right bound, so recurs to right direction. Position ② is opposite of position ①, recurs to left direction. Position ③ means our check interval is included the interval we need, so recurs deeply.
72
72
73
73

74
+
74
75
There are common part from the two parts of code above - **recurs deeply below, and update data up**. So we can decouple this operation named `func pushUp(lson: LazySegmentTree, rson: LazySegmentTree)`:
@@ -132,11 +139,13 @@ It is a `O(n)` time operation, which make the interval operation uses `O(nlogn)`
132
139
Check the data structure of Segment Tree again:
133
140
134
141

142
+
135
143
We only catch the root node in programming. If we want to explore the bottom of the tree, and use `pushUp` to update every node, the task will be reached. So it asked us to traverse the tree, that spent `O(n)` time to do this with any way. This can't conform our expectations.
136
144
137
145
Then we started to think about `pushDown` to update down from the root. **After we update the parent, the data continued to distributed to its children according to law.** But it still need `O(n)` time to do this. Keep thinking, we **only update the parent, and to update the children when `query` time**. Yeah, that's the key of **lazy propagation**. Because the recursing direct of the `query` and `update interval` is same. So we got it! 😁 Let's check this sample:
138
146
139
147

148
+
140
149
`update` make the subscript 1...3 elements plus 2, so we make the 1st node in 2 depth and 3rd in 3 depth get a *lazy mark*, which means these node need to be updated. And we shouldn't add a *lazy mark* for root node, because it was updated before the `pushDown` in the first recursing.
141
150
142
151
In `query` operation, we accord to the original method to recurs the tree, and find the 1st node held *lazy mark* in 2 depth, so to update it. It's the same situation about the 1st node in 3 depth.
@@ -147,85 +156,115 @@ This is the complete implementation about the Sum Segment Tree with interval upd
147
156
148
157
```swift
149
158
publicclassLazySegmentTree {
159
+
150
160
privatevar value: Int
161
+
151
162
privatevar leftBound: Int
163
+
152
164
privatevar rightBound: Int
165
+
153
166
privatevar leftChild: LazySegmentTree?
167
+
154
168
privatevar rightChild: LazySegmentTree?
169
+
155
170
// Interval Update Lazy Element
156
171
privatevar lazyValue: Int
172
+
157
173
// MARK: - Push Up Operation
174
+
// Description: pushUp() - update items to the top
Here we add a new property for Segment Tree to represent *lazy mark*. And it is a incremental value for Sum Segment Tree. If the `lazyValue` isn't equal to zero, the current node need to be updated. And its real value is equal to `value + lazyValue * (rightBound - leftBound + 1)`.
239
278
240
279
```swift
241
-
// MARK: - Push Down Operation
280
+
// MARK: - Push Down Operation
281
+
// Description: pushDown() - update items to the bottom
0 commit comments