-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
/
Copy pathSolution.go
75 lines (68 loc) · 1.22 KB
/
Solution.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
func lengthOfLIS(nums []int, k int) int {
mx := slices.Max(nums)
tree := newSegmentTree(mx)
ans := 1
for _, v := range nums {
t := tree.query(1, v-k, v-1) + 1
ans = max(ans, t)
tree.modify(1, v, t)
}
return ans
}
type node struct {
l int
r int
v int
}
type segmentTree struct {
tr []*node
}
func newSegmentTree(n int) *segmentTree {
tr := make([]*node, n<<2)
for i := range tr {
tr[i] = &node{}
}
t := &segmentTree{tr}
t.build(1, 1, n)
return t
}
func (t *segmentTree) build(u, l, r int) {
t.tr[u].l, t.tr[u].r = l, r
if l == r {
return
}
mid := (l + r) >> 1
t.build(u<<1, l, mid)
t.build(u<<1|1, mid+1, r)
t.pushup(u)
}
func (t *segmentTree) modify(u, x, v int) {
if t.tr[u].l == x && t.tr[u].r == x {
t.tr[u].v = v
return
}
mid := (t.tr[u].l + t.tr[u].r) >> 1
if x <= mid {
t.modify(u<<1, x, v)
} else {
t.modify(u<<1|1, x, v)
}
t.pushup(u)
}
func (t *segmentTree) query(u, l, r int) int {
if t.tr[u].l >= l && t.tr[u].r <= r {
return t.tr[u].v
}
mid := (t.tr[u].l + t.tr[u].r) >> 1
v := 0
if l <= mid {
v = t.query(u<<1, l, r)
}
if r > mid {
v = max(v, t.query(u<<1|1, l, r))
}
return v
}
func (t *segmentTree) pushup(u int) {
t.tr[u].v = max(t.tr[u<<1].v, t.tr[u<<1|1].v)
}