1
- //: Playground - noun: a place where people can play
2
-
3
- // last checked with Xcode 9.0b4
4
- #if swift(>=4.0)
5
- print ( " Hello, Swift 4! " )
6
- #endif
7
-
8
- //protocol SegmentTree<T> {
9
- // func pushUp(lson: T, rson: T)
10
- // func pushDown(round: Int, lson: T, rson: T)
11
- //}
12
-
13
1
public class LazySegmentTree {
14
2
15
3
private var value : Int
@@ -26,22 +14,20 @@ public class LazySegmentTree {
26
14
private var lazyValue : Int
27
15
28
16
// MARK: - Push Up Operation
29
- // Description: 这里是 push up 操作,用来对 Segment Tree 向上更新
17
+ // Description: pushUp() - update items to the top
30
18
private func pushUp( lson: LazySegmentTree , rson: LazySegmentTree ) {
31
19
self . value = lson. value + rson. value
32
20
}
33
21
34
22
// MARK: - Push Down Operation
35
- // Description: 这里是 push down 操作,用来对 Segment Tree 向下更新
36
- // Open Interface Function: 此处应该开放方法对齐进行 Override
23
+ // Description: pushDown() - update items to the bottom
37
24
private func pushDown( round: Int , lson: LazySegmentTree , rson: LazySegmentTree ) {
38
- if lazyValue != 0 {
39
- lson. lazyValue += lazyValue
40
- rson. lazyValue += lazyValue
41
- lson. value += lazyValue * ( round - ( round >> 1 ) )
42
- rson. value += lazyValue * ( round >> 1 )
43
- lazyValue = 0
44
- }
25
+ guard lazyValue != 0 else { return }
26
+ lson. lazyValue += lazyValue
27
+ rson. lazyValue += lazyValue
28
+ lson. value += lazyValue * ( round - ( round >> 1 ) )
29
+ rson. value += lazyValue * ( round >> 1 )
30
+ lazyValue = 0
45
31
}
46
32
47
33
public init ( array: [ Int ] , leftBound: Int , rightBound: Int ) {
@@ -50,16 +36,17 @@ public class LazySegmentTree {
50
36
self . value = 0
51
37
self . lazyValue = 0
52
38
53
- if leftBound == rightBound {
39
+ guard leftBound != rightBound else {
54
40
value = array [ leftBound]
55
41
return
56
42
}
57
43
58
- let middle = ( leftBound + rightBound) / 2
44
+ let middle = leftBound + ( rightBound - leftBound ) / 2
59
45
leftChild = LazySegmentTree ( array: array, leftBound: leftBound, rightBound: middle)
60
46
rightChild = LazySegmentTree ( array: array, leftBound: middle + 1 , rightBound: rightBound)
61
- pushUp ( lson: leftChild!, rson: rightChild!)
62
-
47
+ if let leftChild = leftChild, let rightChild = rightChild {
48
+ pushUp ( lson: leftChild, rson: rightChild)
49
+ }
63
50
}
64
51
65
52
public convenience init ( array: [ Int ] ) {
@@ -75,7 +62,7 @@ public class LazySegmentTree {
75
62
76
63
pushDown ( round: self . rightBound - self . leftBound + 1 , lson: leftChild, rson: rightChild)
77
64
78
- let middle = ( self . leftBound + self . rightBound) / 2
65
+ let middle = self . leftBound + ( self . rightBound - self . leftBound ) / 2
79
66
var result : Int = 0
80
67
81
68
if leftBound <= middle { result += leftChild. query ( leftBound: leftBound, rightBound: rightBound) }
@@ -86,14 +73,14 @@ public class LazySegmentTree {
86
73
87
74
// MARK: - One Item Update
88
75
public func update( index: Int , incremental: Int ) {
89
- if self . leftBound == self . rightBound {
76
+ guard self . leftBound != self . rightBound else {
90
77
self . value += incremental
91
78
return
92
79
}
93
80
guard let leftChild = leftChild else { fatalError ( " leftChild should not be nil " ) }
94
81
guard let rightChild = rightChild else { fatalError ( " rightChild should not be nil " ) }
95
82
96
- let middle = ( self . leftBound + self . rightBound) / 2
83
+ let middle = self . rightBound + ( self . leftBound - self . rightBound) / 2
97
84
98
85
if index <= middle { leftChild. update ( index: index, incremental: incremental) }
99
86
else { rightChild. update ( index: index, incremental: incremental) }
@@ -113,7 +100,7 @@ public class LazySegmentTree {
113
100
114
101
pushDown ( round: self . rightBound - self . leftBound + 1 , lson: leftChild, rson: rightChild)
115
102
116
- let middle = ( self . leftBound + self . rightBound) / 2
103
+ let middle = self . rightBound + ( self . leftBound - self . rightBound) / 2
117
104
118
105
if leftBound <= middle { leftChild. update ( leftBound: leftBound, rightBound: rightBound, incremental: incremental) }
119
106
if middle < rightBound { rightChild. update ( leftBound: leftBound, rightBound: rightBound, incremental: incremental) }
@@ -140,8 +127,3 @@ for index in 2 ... 5 {
140
127
141
128
sumSegmentTree. update ( leftBound: 0 , rightBound: 5 , incremental: 2 )
142
129
print ( sumSegmentTree. query ( leftBound: 0 , rightBound: 2 ) )
143
-
144
-
145
-
146
-
147
-
0 commit comments