-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
/
Copy pathSolution2.go
91 lines (80 loc) · 1.64 KB
/
Solution2.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
type Node struct {
l, r, v int
}
type SegmentTree struct {
tr []Node
nums []int
}
func newSegmentTree(nums []int) *SegmentTree {
n := len(nums)
tr := make([]Node, n<<2)
for i := range tr {
tr[i] = Node{}
}
tree := &SegmentTree{
tr: tr,
nums: nums,
}
tree.build(1, 1, n)
return tree
}
func (tree *SegmentTree) build(u, l, r int) {
tree.tr[u].l, tree.tr[u].r = l, r
if l == r {
tree.tr[u].v = tree.nums[l-1]
return
}
mid := (l + r) >> 1
tree.build(u<<1, l, mid)
tree.build(u<<1|1, mid+1, r)
tree.pushup(u)
}
func (tree *SegmentTree) modify(u, x, v int) {
if tree.tr[u].l == x && tree.tr[u].r == x {
tree.tr[u].v = v
return
}
mid := (tree.tr[u].l + tree.tr[u].r) >> 1
if x <= mid {
tree.modify(u<<1, x, v)
} else {
tree.modify(u<<1|1, x, v)
}
tree.pushup(u)
}
func (tree *SegmentTree) query(u, l, r int) (v int) {
if tree.tr[u].l >= l && tree.tr[u].r <= r {
return tree.tr[u].v
}
mid := (tree.tr[u].l + tree.tr[u].r) >> 1
if l <= mid {
v += tree.query(u<<1, l, r)
}
if r > mid {
v += tree.query(u<<1|1, l, r)
}
return v
}
func (tree *SegmentTree) pushup(u int) {
tree.tr[u].v = tree.tr[u<<1].v + tree.tr[u<<1|1].v
}
type NumArray struct {
tree *SegmentTree
}
func Constructor(nums []int) NumArray {
return NumArray{
tree: newSegmentTree(nums),
}
}
func (this *NumArray) Update(index int, val int) {
this.tree.modify(1, index+1, val)
}
func (this *NumArray) SumRange(left int, right int) int {
return this.tree.query(1, left+1, right+1)
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(index,val);
* param_2 := obj.SumRange(left,right);
*/