ac-library-rb 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/README.md +8 -1
- data/document_en/segtree.md +17 -3
- data/document_ja/segtree.md +34 -6
- data/lib/ac-library-rb/version.rb +1 -1
- data/lib/dsu.rb +6 -1
- data/lib/fenwick_tree.rb +1 -0
- data/lib/floor_sum.rb +34 -9
- data/lib/scc.rb +6 -7
- data/lib/segtree.rb +13 -13
- data/lib_lock/ac-library-rb/dsu.rb +6 -1
- data/lib_lock/ac-library-rb/fenwick_tree.rb +1 -0
- data/lib_lock/ac-library-rb/floor_sum.rb +34 -9
- data/lib_lock/ac-library-rb/scc.rb +6 -7
- data/lib_lock/ac-library-rb/segtree.rb +13 -13
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7eb404ec2eab941e961da5a9cc0e19b87858a33101c791750a2e33d61781f8b8
|
4
|
+
data.tar.gz: a341ee2e478add1f3e611071213911dd919e7229ca3cc8cc9c19880e3e471467
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 053064e9c40fe91e306a7695906bec15ef8752c3ddfa54f7954bf83f5954a626370f9390034f0777c0e403460f7ed650707a89be6a02d88c49cb52cdb0da5ffb
|
7
|
+
data.tar.gz: 910dd3b9d493efba69cfe458a41a82c28ba4b5dde013521f56b29fbe7f3737d7d82fd50424b205c98683f0691da843de6ffc3ec58dd5cdf75e7d7ed1d94f1185
|
data/.rubocop.yml
CHANGED
@@ -121,6 +121,9 @@ Style/BlockDelimiters:
|
|
121
121
|
- 'test/z_algorithm_test.rb'
|
122
122
|
Style/Documentation:
|
123
123
|
Enabled: false
|
124
|
+
tyle/EmptyElse:
|
125
|
+
Exclude:
|
126
|
+
- 'test/segtree_test.rb'
|
124
127
|
Style/GlobalVars:
|
125
128
|
AutoCorrect: false
|
126
129
|
Exclude:
|
@@ -128,6 +131,9 @@ Style/GlobalVars:
|
|
128
131
|
- 'test/lazy_segtree_test.rb'
|
129
132
|
Style/FrozenStringLiteralComment:
|
130
133
|
Enabled: false
|
134
|
+
Style/InfiniteLoop:
|
135
|
+
Exclude:
|
136
|
+
- 'lib/floor_sum.rb'
|
131
137
|
Style/InverseMethods:
|
132
138
|
AutoCorrect: false
|
133
139
|
Exclude:
|
data/README.md
CHANGED
@@ -100,7 +100,14 @@ $ rake
|
|
100
100
|
$ ruby test/fenwick_tree_test.rb
|
101
101
|
```
|
102
102
|
|
103
|
-
# Other
|
103
|
+
# Other
|
104
|
+
|
105
|
+
## Other languages's ac-library
|
106
|
+
|
107
|
+
- [Unofficial Portings of AtCoder Library](https://docs.google.com/spreadsheets/d/19jMAqUbv98grVkLV_Lt54x5B8ILoTcvBzG8EbSvf5gY/edit#gid=0) (by [not522-san](https://github.com/not522))
|
108
|
+
|
109
|
+
|
110
|
+
## Other language Japanese version
|
104
111
|
|
105
112
|
[README 日本語バージョン(ver. Japanese)](README.ja.md)
|
106
113
|
- [ライブラリ目次: index.md](https://github.com/universato/ac-library-rb/blob/master/document_ja/index.md)
|
data/document_en/segtree.md
CHANGED
@@ -104,26 +104,38 @@ It returns `op(a[0], ..., a[n - 1])`.
|
|
104
104
|
seg.max_right(l, &f)
|
105
105
|
```
|
106
106
|
|
107
|
+
It applies binary search on the segment tree.
|
108
|
+
|
109
|
+
It returns an index `r` that satisfies both of the following.
|
110
|
+
|
111
|
+
- `r = l` or `f(prod(l, r)) = true`
|
112
|
+
- `r = n` or `f(prod(l, r + 1)) = false`
|
113
|
+
|
114
|
+
|
107
115
|
**Constraints**
|
108
116
|
|
117
|
+
- `f(e) = true`
|
109
118
|
- `0 ≦ l ≦ n`
|
110
119
|
|
111
120
|
**Complexity**
|
112
121
|
|
113
122
|
- `O(log n)`
|
114
123
|
|
115
|
-
It applies binary search on the segment tree.
|
116
|
-
|
117
124
|
### min_left(r, &f) -> Integer
|
118
125
|
|
119
126
|
```ruby
|
120
127
|
seg.min_left(r, &f)
|
121
128
|
```
|
122
129
|
|
123
|
-
It applies binary search on the segment tree.
|
130
|
+
It applies binary search on the segment tree.
|
131
|
+
It returns an index l that satisfies both of the following.
|
132
|
+
|
133
|
+
- `l = r` or `f(prod(l, r)) = true`
|
134
|
+
- `l = 0` or `f(prod(l - 1, r)) = false`
|
124
135
|
|
125
136
|
**Constraints**
|
126
137
|
|
138
|
+
- `f(e) = true`
|
127
139
|
- `0 ≦ r ≦ n`
|
128
140
|
|
129
141
|
**Complexity**
|
@@ -133,6 +145,8 @@ It applies binary search on the segment tree.
|
|
133
145
|
## Verified
|
134
146
|
|
135
147
|
- [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
|
148
|
+
- [AC Code(884ms) max_right](https://atcoder.jp/contests/practice2/submissions/23196480)
|
149
|
+
- [AC Code(914ms) min_left](https://atcoder.jp/contests/practice2/submissions/23197311)
|
136
150
|
- [F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
|
137
151
|
- [AC Code(1538ms)](https://atcoder.jp/contests/abc185/submissions/18746817): Segtree(xor)
|
138
152
|
- [AC Code(821ms)](https://atcoder.jp/contests/abc185/submissions/18769200): FenwickTree(BIT) xor
|
data/document_ja/segtree.md
CHANGED
@@ -94,11 +94,24 @@ seg.all_prod
|
|
94
94
|
seg.max_right(l, &f)
|
95
95
|
```
|
96
96
|
|
97
|
-
Segtree
|
97
|
+
Segtree上で`l <= r <= n`の範囲で、`f(prod(l, r))`の結果を二分探索をして条件に当てはまる`r`を返します。
|
98
98
|
|
99
|
-
|
99
|
+
以下の条件を両方満たす `r` (`l <= r <= n`)を(いずれか一つ)返します。
|
100
100
|
|
101
|
-
|
101
|
+
- `r = l` もしくは `f(prod(l, r))`が`true`となる`r`
|
102
|
+
- `r = n` もしくは `f(prod(l, r + 1))`が`false`となる`r`
|
103
|
+
|
104
|
+
`prod(l, r)`は半開区間`[l, r)`であることに注意。
|
105
|
+
|
106
|
+
**制約**
|
107
|
+
|
108
|
+
- `f`を同じ引数で呼んだとき、返り値は同じ。
|
109
|
+
- `f(e)`が`true`
|
110
|
+
- `0 ≦ l ≦ n`
|
111
|
+
|
112
|
+
**計算量**
|
113
|
+
|
114
|
+
- `O(log n)`
|
102
115
|
|
103
116
|
### min_left(r, &f) -> Integer
|
104
117
|
|
@@ -106,15 +119,30 @@ Segtree上で二分探索をします。
|
|
106
119
|
seg.min_left(r, &f)
|
107
120
|
```
|
108
121
|
|
109
|
-
Segtree
|
122
|
+
Segtree上で`0 <= l <= r`の範囲で、`f(prod(l, r))`の結果を二分探索をして条件に当てはまる`l`を返します。
|
123
|
+
|
124
|
+
以下の条件を両方満たす `l` (`0 <= l <= r`)を(いずれか一つ)返します。
|
110
125
|
|
111
|
-
|
126
|
+
- `l = r` もしくは `f(prod(l, r))`が`true`となる`l`
|
127
|
+
- `l = 0` もしくは `f(prod(l - 1, r))`が`false`となる`l`
|
128
|
+
|
129
|
+
`prod(l, r)`は半開区間`[l, r)`であることに注意。
|
130
|
+
|
131
|
+
**制約**
|
132
|
+
|
133
|
+
- `f`を同じ引数で呼んだとき、返り値は同じ。
|
134
|
+
- `f(e)`が`true`
|
135
|
+
- `0 ≦ l ≦ n`
|
136
|
+
|
137
|
+
**計算量**
|
112
138
|
|
113
|
-
|
139
|
+
- `O(log n)`
|
114
140
|
|
115
141
|
## Verified
|
116
142
|
|
117
143
|
- [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
|
144
|
+
- [AC Code(884ms) max_right](https://atcoder.jp/contests/practice2/submissions/23196480)
|
145
|
+
- [AC Code(914ms) min_left](https://atcoder.jp/contests/practice2/submissions/23197311)
|
118
146
|
|
119
147
|
- [ABC185: F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
|
120
148
|
- xorのセグメントツリーの基本的な典型問題です。FenwickTree(BIT)をxorに改造するだけでも解けます。
|
data/lib/dsu.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# Disjoint Set Union
|
2
2
|
class DSU
|
3
3
|
def initialize(n = 0)
|
4
|
+
@n = n
|
5
|
+
@parent_or_size = Array.new(n, -1)
|
4
6
|
# root node: -1 * component size
|
5
7
|
# otherwise: parent
|
6
|
-
@parent_or_size = Array.new(n, -1)
|
7
8
|
end
|
8
9
|
|
9
10
|
attr_accessor :parent_or_size
|
@@ -25,6 +26,10 @@ class DSU
|
|
25
26
|
alias same? same
|
26
27
|
|
27
28
|
def leader(a)
|
29
|
+
unless 0 <= a && a < @n
|
30
|
+
raise ArgumentError.new, "#{a} is out of range 0 <= arg < size"
|
31
|
+
end
|
32
|
+
|
28
33
|
@parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
|
29
34
|
end
|
30
35
|
alias root leader
|
data/lib/fenwick_tree.rb
CHANGED
data/lib/floor_sum.rb
CHANGED
@@ -1,19 +1,44 @@
|
|
1
1
|
def floor_sum(n, m, a, b)
|
2
|
+
raise ArgumentError if n < 0 || m < 1
|
3
|
+
|
2
4
|
res = 0
|
3
5
|
|
4
|
-
if a
|
5
|
-
|
6
|
-
a
|
6
|
+
if a < 0
|
7
|
+
a2 = a % m
|
8
|
+
res -= n * (n - 1) / 2 * ((a2 - a) / m)
|
9
|
+
a = a2
|
7
10
|
end
|
8
11
|
|
9
|
-
if b
|
10
|
-
|
11
|
-
b
|
12
|
+
if b < 0
|
13
|
+
b2 = b % m
|
14
|
+
res -= n * ((b2 - b) / m)
|
15
|
+
b = b2
|
12
16
|
end
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
res + floor_sum_unsigned(n, m, a, b)
|
19
|
+
end
|
20
|
+
|
21
|
+
def floor_sum_unsigned(n, m, a, b)
|
22
|
+
res = 0
|
23
|
+
|
24
|
+
while true
|
25
|
+
if a >= m
|
26
|
+
res += n * (n - 1) / 2 * (a / m)
|
27
|
+
a %= m
|
28
|
+
end
|
29
|
+
|
30
|
+
if b >= m
|
31
|
+
res += n * (b / m)
|
32
|
+
b %= m
|
33
|
+
end
|
34
|
+
|
35
|
+
y_max = a * n + b
|
36
|
+
break if y_max < m
|
37
|
+
|
38
|
+
n = y_max / m
|
39
|
+
b = y_max % m
|
40
|
+
m, a = a, m
|
41
|
+
end
|
16
42
|
|
17
|
-
res += floor_sum(y_max / m, a, m, y_max % m)
|
18
43
|
res
|
19
44
|
end
|
data/lib/scc.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Strongly Connected Components
|
2
|
-
class
|
2
|
+
class SCC
|
3
3
|
# initialize graph with n vertices
|
4
4
|
def initialize(n = 0)
|
5
5
|
@n, @edges = n, []
|
@@ -10,6 +10,7 @@ class SCCGraph
|
|
10
10
|
raise "invalid params" unless (0...@n).include? from and (0...@n).include? to
|
11
11
|
|
12
12
|
@edges << [from, to]
|
13
|
+
self
|
13
14
|
end
|
14
15
|
|
15
16
|
# returns list of strongly connected components
|
@@ -17,10 +18,8 @@ class SCCGraph
|
|
17
18
|
# O(@n + @edges.size)
|
18
19
|
def scc
|
19
20
|
group_num, ids = scc_ids
|
20
|
-
counts = [0] * group_num
|
21
|
-
ids.each { |x| counts[x] += 1 }
|
22
21
|
groups = Array.new(group_num) { [] }
|
23
|
-
ids.each_with_index { |
|
22
|
+
ids.each_with_index { |id, i| groups[id] << i }
|
24
23
|
groups
|
25
24
|
end
|
26
25
|
|
@@ -72,6 +71,6 @@ class SCCGraph
|
|
72
71
|
end
|
73
72
|
|
74
73
|
# class alias
|
75
|
-
StronglyConnectedComponents =
|
76
|
-
|
77
|
-
SCCG =
|
74
|
+
StronglyConnectedComponents = SCC
|
75
|
+
SCCGraph = SCC
|
76
|
+
SCCG = SCC
|
data/lib/segtree.rb
CHANGED
@@ -127,19 +127,19 @@ class Segtree
|
|
127
127
|
@d[k] = @op.call(@d[2 * k], @d[2 * k + 1])
|
128
128
|
end
|
129
129
|
|
130
|
-
def inspect
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
130
|
+
# def inspect # for debug
|
131
|
+
# t = 0
|
132
|
+
# res = "SegmentTree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
|
133
|
+
# a = @d[1, @d.size - 1]
|
134
|
+
# a.each_with_index do |e, i|
|
135
|
+
# res << e.to_s << ' '
|
136
|
+
# if t == i && i < @leaf_size
|
137
|
+
# res << "\n "
|
138
|
+
# t = t * 2 + 2
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
# res
|
142
|
+
# end
|
143
143
|
end
|
144
144
|
|
145
145
|
SegTree = Segtree
|
@@ -2,9 +2,10 @@ module AcLibraryRb
|
|
2
2
|
# Disjoint Set Union
|
3
3
|
class DSU
|
4
4
|
def initialize(n = 0)
|
5
|
+
@n = n
|
6
|
+
@parent_or_size = Array.new(n, -1)
|
5
7
|
# root node: -1 * component size
|
6
8
|
# otherwise: parent
|
7
|
-
@parent_or_size = Array.new(n, -1)
|
8
9
|
end
|
9
10
|
|
10
11
|
attr_accessor :parent_or_size
|
@@ -26,6 +27,10 @@ module AcLibraryRb
|
|
26
27
|
alias same? same
|
27
28
|
|
28
29
|
def leader(a)
|
30
|
+
unless 0 <= a && a < @n
|
31
|
+
raise ArgumentError.new, "#{a} is out of range 0 <= arg < size"
|
32
|
+
end
|
33
|
+
|
29
34
|
@parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
|
30
35
|
end
|
31
36
|
alias root leader
|
@@ -1,21 +1,46 @@
|
|
1
1
|
module AcLibraryRb
|
2
2
|
def floor_sum(n, m, a, b)
|
3
|
+
raise ArgumentError if n < 0 || m < 1
|
4
|
+
|
3
5
|
res = 0
|
4
6
|
|
5
|
-
if a
|
6
|
-
|
7
|
-
a
|
7
|
+
if a < 0
|
8
|
+
a2 = a % m
|
9
|
+
res -= n * (n - 1) / 2 * ((a2 - a) / m)
|
10
|
+
a = a2
|
8
11
|
end
|
9
12
|
|
10
|
-
if b
|
11
|
-
|
12
|
-
b
|
13
|
+
if b < 0
|
14
|
+
b2 = b % m
|
15
|
+
res -= n * ((b2 - b) / m)
|
16
|
+
b = b2
|
13
17
|
end
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
res + floor_sum_unsigned(n, m, a, b)
|
20
|
+
end
|
21
|
+
|
22
|
+
def floor_sum_unsigned(n, m, a, b)
|
23
|
+
res = 0
|
24
|
+
|
25
|
+
while true
|
26
|
+
if a >= m
|
27
|
+
res += n * (n - 1) / 2 * (a / m)
|
28
|
+
a %= m
|
29
|
+
end
|
30
|
+
|
31
|
+
if b >= m
|
32
|
+
res += n * (b / m)
|
33
|
+
b %= m
|
34
|
+
end
|
35
|
+
|
36
|
+
y_max = a * n + b
|
37
|
+
break if y_max < m
|
38
|
+
|
39
|
+
n = y_max / m
|
40
|
+
b = y_max % m
|
41
|
+
m, a = a, m
|
42
|
+
end
|
17
43
|
|
18
|
-
res += floor_sum(y_max / m, a, m, y_max % m)
|
19
44
|
res
|
20
45
|
end
|
21
46
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module AcLibraryRb
|
2
2
|
# Strongly Connected Components
|
3
|
-
class
|
3
|
+
class SCC
|
4
4
|
# initialize graph with n vertices
|
5
5
|
def initialize(n = 0)
|
6
6
|
@n, @edges = n, []
|
@@ -11,6 +11,7 @@ module AcLibraryRb
|
|
11
11
|
raise "invalid params" unless (0...@n).include? from and (0...@n).include? to
|
12
12
|
|
13
13
|
@edges << [from, to]
|
14
|
+
self
|
14
15
|
end
|
15
16
|
|
16
17
|
# returns list of strongly connected components
|
@@ -18,10 +19,8 @@ module AcLibraryRb
|
|
18
19
|
# O(@n + @edges.size)
|
19
20
|
def scc
|
20
21
|
group_num, ids = scc_ids
|
21
|
-
counts = [0] * group_num
|
22
|
-
ids.each { |x| counts[x] += 1 }
|
23
22
|
groups = Array.new(group_num) { [] }
|
24
|
-
ids.each_with_index { |
|
23
|
+
ids.each_with_index { |id, i| groups[id] << i }
|
25
24
|
groups
|
26
25
|
end
|
27
26
|
|
@@ -73,7 +72,7 @@ module AcLibraryRb
|
|
73
72
|
end
|
74
73
|
|
75
74
|
# class alias
|
76
|
-
StronglyConnectedComponents =
|
77
|
-
|
78
|
-
SCCG =
|
75
|
+
StronglyConnectedComponents = SCC
|
76
|
+
SCCGraph = SCC
|
77
|
+
SCCG = SCC
|
79
78
|
end
|
@@ -128,19 +128,19 @@ module AcLibraryRb
|
|
128
128
|
@d[k] = @op.call(@d[2 * k], @d[2 * k + 1])
|
129
129
|
end
|
130
130
|
|
131
|
-
def inspect
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
131
|
+
# def inspect # for debug
|
132
|
+
# t = 0
|
133
|
+
# res = "SegmentTree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
|
134
|
+
# a = @d[1, @d.size - 1]
|
135
|
+
# a.each_with_index do |e, i|
|
136
|
+
# res << e.to_s << ' '
|
137
|
+
# if t == i && i < @leaf_size
|
138
|
+
# res << "\n "
|
139
|
+
# t = t * 2 + 2
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
# res
|
143
|
+
# end
|
144
144
|
end
|
145
145
|
|
146
146
|
SegTree = Segtree
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ac-library-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- universato
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -151,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
requirements: []
|
154
|
-
rubygems_version: 3.2.
|
154
|
+
rubygems_version: 3.2.11
|
155
155
|
signing_key:
|
156
156
|
specification_version: 4
|
157
157
|
summary: ac-library-rb is a ruby port of AtCoder Library (ACL).
|