-
Notifications
You must be signed in to change notification settings - Fork 30
/
count_smaller-Segment-and-BIT-way-Q315.rb
71 lines (64 loc) · 1.28 KB
/
count_smaller-Segment-and-BIT-way-Q315.rb
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
# Q-315: segment tree and bit-tree way
# 3/dec/2022
# @param {Integer[]} nums
# @return {Integer[]}
# Q-315: segment tree way
def count_smaller(nums)
offset = 10000
size = 1 + offset * 2
seg = [0] * size * 2
result = []
(nums.size - 1).downto(0) do |i|
smaller = query(nums[i] + offset, seg, size)
result << smaller
update(nums[i] + offset, seg, size)
end
result.reverse
end
def update(i, seg, size)
i += size
seg[i] += 1
while i > 1
i /= 2
seg[i] = seg[i * 2] + seg[i * 2 + 1]
end
end
def query(r, seg, size)
l, r, result = size, size + r, 0
while l < r
(result += seg[l]; l += 1) if l.odd?
(r -= 1; result += seg[r]) if r.odd?
l, r = l / 2, r / 2
end
result
end
# Q-315: bit way
def count_smaller(nums)
offset = 10000
size = 2 * offset + 2
bit = [0] * size
result = []
(nums.size - 1).downto(0) do |i|
smaller = query(nums[i] + offset, bit)
result << smaller
update(nums[i] + offset + 1, bit, size)
end
result.reverse
end
def update(i, bit, size)
while i < size
bit[i] += 1
i += i & -i
end
end
def query(i, bit)
result = 0
while i > 0
result += bit[i]
i -= i & -i
end
result
end
p count_smaller([5, 2, 6, 1]) == [2, 1, 1, 0]
p count_smaller([-1, -1]) == [0, 0]
p count_smaller([-1, -1])