ac-library-rb 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- 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).
|