ac-library-rb 0.5.0 → 0.6.0
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 +12 -0
- data/README.ja.md +102 -4
- data/README.md +73 -1
- data/Rakefile +2 -1
- data/ac-library-rb.gemspec +3 -2
- data/bin/lock_lib.rb +13 -7
- data/document_en/dsu.md +2 -2
- data/document_en/lazy_segtree.md +20 -4
- data/document_en/max_flow.md +1 -1
- data/document_en/min_cost_flow.md +1 -1
- data/document_en/segtree.md +36 -3
- data/document_en/two_sat.md +1 -1
- data/document_ja/dsu.md +1 -3
- data/document_ja/lazy_segtree.md +63 -19
- data/document_ja/max_flow.md +1 -1
- data/document_ja/min_cost_flow.md +1 -1
- data/document_ja/scc.md +4 -3
- data/document_ja/segtree.md +49 -8
- data/document_ja/two_sat.md +1 -1
- data/lib/ac-library-rb/version.rb +1 -1
- data/lib/convolution.rb +21 -0
- data/lib/core_ext/all.rb +11 -0
- data/lib/dsu.rb +9 -6
- data/lib/fenwick_tree.rb +22 -8
- data/lib/floor_sum.rb +33 -10
- data/lib/lazy_segtree.rb +83 -10
- data/lib/max_flow.rb +10 -4
- data/lib/min_cost_flow.rb +13 -7
- data/lib/modint.rb +3 -1
- data/lib/scc.rb +21 -13
- data/lib/segtree.rb +38 -26
- data/lib/suffix_array.rb +8 -8
- data/lib/two_sat.rb +5 -3
- data/lib_lock/ac-library-rb.rb +2 -0
- data/lib_lock/ac-library-rb/convolution.rb +21 -0
- data/lib_lock/ac-library-rb/core_ext/all.rb +11 -0
- data/lib_lock/ac-library-rb/core_ext/modint.rb +3 -3
- data/lib_lock/ac-library-rb/dsu.rb +9 -6
- data/lib_lock/ac-library-rb/fenwick_tree.rb +22 -8
- data/lib_lock/ac-library-rb/floor_sum.rb +33 -10
- data/lib_lock/ac-library-rb/lazy_segtree.rb +83 -10
- data/lib_lock/ac-library-rb/max_flow.rb +10 -4
- data/lib_lock/ac-library-rb/min_cost_flow.rb +13 -7
- data/lib_lock/ac-library-rb/modint.rb +3 -1
- data/lib_lock/ac-library-rb/scc.rb +21 -13
- data/lib_lock/ac-library-rb/segtree.rb +38 -26
- data/lib_lock/ac-library-rb/suffix_array.rb +8 -8
- data/lib_lock/ac-library-rb/two_sat.rb +5 -3
- metadata +20 -4
@@ -162,7 +162,9 @@ module AcLibraryRb
|
|
162
162
|
|
163
163
|
def inv_internal(a)
|
164
164
|
if $_mod_is_prime
|
165
|
-
|
165
|
+
raise(RangeError, 'no inverse') if a == 0
|
166
|
+
|
167
|
+
a.pow($_mod - 2, $_mod)
|
166
168
|
else
|
167
169
|
g, x = ModInt.inv_gcd(a, $_mod)
|
168
170
|
g == 1 ? x : raise(RangeError, 'no inverse')
|
@@ -1,16 +1,30 @@
|
|
1
1
|
module AcLibraryRb
|
2
2
|
# Strongly Connected Components
|
3
|
-
class
|
3
|
+
class SCC
|
4
4
|
# initialize graph with n vertices
|
5
|
-
def initialize(n
|
6
|
-
@n
|
5
|
+
def initialize(n)
|
6
|
+
@n = n
|
7
|
+
@edges = []
|
7
8
|
end
|
8
9
|
|
9
10
|
# add directed edge
|
10
11
|
def add_edge(from, to)
|
11
|
-
|
12
|
+
unless 0 <= from && from < @n and 0 <= to && to < @n
|
13
|
+
msg = "Wrong params: from=#{from} and to=#{to} must be in 0...#{@n}"
|
14
|
+
raise ArgumentError.new(msg)
|
15
|
+
end
|
12
16
|
|
13
17
|
@edges << [from, to]
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_edges(edges)
|
22
|
+
edges.each{ |from, to| add_edge(from, to) }
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(x, to = nil)
|
27
|
+
to ? add_edge(x, to) : add_edges(x)
|
14
28
|
end
|
15
29
|
|
16
30
|
# returns list of strongly connected components
|
@@ -18,10 +32,8 @@ module AcLibraryRb
|
|
18
32
|
# O(@n + @edges.size)
|
19
33
|
def scc
|
20
34
|
group_num, ids = scc_ids
|
21
|
-
counts = [0] * group_num
|
22
|
-
ids.each { |x| counts[x] += 1 }
|
23
35
|
groups = Array.new(group_num) { [] }
|
24
|
-
ids.each_with_index { |
|
36
|
+
ids.each_with_index { |id, i| groups[id] << i }
|
25
37
|
groups
|
26
38
|
end
|
27
39
|
|
@@ -60,7 +72,8 @@ module AcLibraryRb
|
|
60
72
|
end
|
61
73
|
|
62
74
|
def csr
|
63
|
-
start
|
75
|
+
start = [0] * (@n + 1)
|
76
|
+
elist = [nil] * @edges.size
|
64
77
|
@edges.each { |(i, _)| start[i + 1] += 1 }
|
65
78
|
@n.times { |i| start[i + 1] += start[i] }
|
66
79
|
counter = start.dup
|
@@ -71,9 +84,4 @@ module AcLibraryRb
|
|
71
84
|
[start, elist]
|
72
85
|
end
|
73
86
|
end
|
74
|
-
|
75
|
-
# class alias
|
76
|
-
StronglyConnectedComponents = SCCGraph
|
77
|
-
SCC = SCCGraph
|
78
|
-
SCCG = SCCGraph
|
79
87
|
end
|
@@ -3,21 +3,21 @@ module AcLibraryRb
|
|
3
3
|
class Segtree
|
4
4
|
attr_reader :d, :op, :n, :leaf_size, :log
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
v =
|
6
|
+
# new(v, e){ |x, y| }
|
7
|
+
# new(v, op, e)
|
8
|
+
def initialize(a0, a1, a2 = nil, &block)
|
9
|
+
if a2.nil?
|
10
|
+
@e, @op = a1, proc(&block)
|
11
|
+
v = (a0.is_a?(Array) ? a0 : [@e] * a0)
|
12
|
+
else
|
13
|
+
@op, @e = a1, a2
|
14
|
+
v = (a0.is_a?(Array) ? a0 : [@e] * a0)
|
12
15
|
end
|
13
16
|
|
14
|
-
@e = e
|
15
|
-
@op = proc(&block)
|
16
|
-
|
17
17
|
@n = v.size
|
18
18
|
@log = (@n - 1).bit_length
|
19
19
|
@leaf_size = 1 << @log
|
20
|
-
@d = Array.new(@leaf_size * 2
|
20
|
+
@d = Array.new(@leaf_size * 2, @e)
|
21
21
|
v.each_with_index { |v_i, i| @d[@leaf_size + i] = v_i }
|
22
22
|
(@leaf_size - 1).downto(1) { |i| update(i) }
|
23
23
|
end
|
@@ -27,12 +27,25 @@ module AcLibraryRb
|
|
27
27
|
@d[q] = x
|
28
28
|
1.upto(@log) { |i| update(q >> i) }
|
29
29
|
end
|
30
|
+
alias []= set
|
30
31
|
|
31
32
|
def get(pos)
|
32
33
|
@d[@leaf_size + pos]
|
33
34
|
end
|
35
|
+
alias [] get
|
36
|
+
|
37
|
+
def prod(l, r = nil)
|
38
|
+
if r.nil? # if 1st argument l is Range
|
39
|
+
if r = l.end
|
40
|
+
r += @n if r < 0
|
41
|
+
r += 1 unless l.exclude_end?
|
42
|
+
else
|
43
|
+
r = @n
|
44
|
+
end
|
45
|
+
l = l.begin
|
46
|
+
l += @n if l < 0
|
47
|
+
end
|
34
48
|
|
35
|
-
def prod(l, r)
|
36
49
|
return @e if l == r
|
37
50
|
|
38
51
|
sml = @e
|
@@ -122,21 +135,20 @@ module AcLibraryRb
|
|
122
135
|
@d[k] = @op.call(@d[2 * k], @d[2 * k + 1])
|
123
136
|
end
|
124
137
|
|
125
|
-
def inspect
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
+
# def inspect # for debug
|
139
|
+
# t = 0
|
140
|
+
# res = "Segtree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
|
141
|
+
# a = @d[1, @d.size - 1]
|
142
|
+
# a.each_with_index do |e, i|
|
143
|
+
# res << e.to_s << ' '
|
144
|
+
# if t == i && i < @leaf_size
|
145
|
+
# res << "\n "
|
146
|
+
# t = t * 2 + 2
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
# res
|
150
|
+
# end
|
138
151
|
end
|
139
152
|
|
140
|
-
SegTree
|
141
|
-
SegmentTree = Segtree
|
153
|
+
SegTree = Segtree
|
142
154
|
end
|
@@ -77,9 +77,7 @@ module AcLibraryRb
|
|
77
77
|
end_l = lms[lms_map[l] + 1] || n
|
78
78
|
end_r = lms[lms_map[r] + 1] || n
|
79
79
|
same = true
|
80
|
-
if end_l - l
|
81
|
-
same = false
|
82
|
-
else
|
80
|
+
if end_l - l == end_r - r
|
83
81
|
while l < end_l
|
84
82
|
break if s[l] != s[r]
|
85
83
|
|
@@ -87,6 +85,8 @@ module AcLibraryRb
|
|
87
85
|
r += 1
|
88
86
|
end
|
89
87
|
same = false if l == n || s[l] != s[r]
|
88
|
+
else
|
89
|
+
same = false
|
90
90
|
end
|
91
91
|
rec_upper += 1 if not same
|
92
92
|
rec_s[lms_map[sorted_lms[i]]] = rec_upper
|
@@ -101,7 +101,11 @@ module AcLibraryRb
|
|
101
101
|
|
102
102
|
# suffix array for array of integers or string
|
103
103
|
def suffix_array(s, upper = nil)
|
104
|
-
if
|
104
|
+
if upper
|
105
|
+
s.each{ |s|
|
106
|
+
raise ArgumentError if s < 0 || upper < s
|
107
|
+
}
|
108
|
+
else
|
105
109
|
case s
|
106
110
|
when Array
|
107
111
|
# compression
|
@@ -119,10 +123,6 @@ module AcLibraryRb
|
|
119
123
|
upper = 255
|
120
124
|
s = s.bytes
|
121
125
|
end
|
122
|
-
else
|
123
|
-
s.each{ |s|
|
124
|
-
raise ArgumentError if s < 0 || upper < s
|
125
|
-
}
|
126
126
|
end
|
127
127
|
|
128
128
|
return sa_is(s, upper)
|
@@ -4,16 +4,18 @@ module AcLibraryRb
|
|
4
4
|
# TwoSAT
|
5
5
|
# Reference: https://github.com/atcoder/ac-library/blob/master/atcoder/twosat.hpp
|
6
6
|
class TwoSAT
|
7
|
-
def initialize(n
|
7
|
+
def initialize(n)
|
8
8
|
@n = n
|
9
9
|
@answer = Array.new(n)
|
10
|
-
@scc =
|
10
|
+
@scc = SCC.new(2 * n)
|
11
11
|
end
|
12
12
|
|
13
13
|
attr_reader :answer
|
14
14
|
|
15
15
|
def add_clause(i, f, j, g)
|
16
|
-
|
16
|
+
unless 0 <= i && i < @n and 0 <= j && j < @n
|
17
|
+
raise RangeError.new
|
18
|
+
end
|
17
19
|
|
18
20
|
@scc.add_edge(2 * i + (f ? 0 : 1), 2 * j + (g ? 1 : 0))
|
19
21
|
@scc.add_edge(2 * j + (g ? 0 : 1), 2 * i + (f ? 1 : 0))
|
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.
|
4
|
+
version: 0.6.0
|
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-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description: |-
|
42
56
|
ac-library-rb is a ruby port of AtCoder Library (ACL).
|
43
57
|
DSU(UnionFind), FenwickTree, PriorityQueue, Segtree, SCC, 2-SAT, suffix_array, lcp_array, z_algorithm, crt, inv_mod, floor_sum, max_flow, min_cost_flow......
|
@@ -90,6 +104,7 @@ files:
|
|
90
104
|
- document_ja/two_sat.md
|
91
105
|
- lib/ac-library-rb/version.rb
|
92
106
|
- lib/convolution.rb
|
107
|
+
- lib/core_ext/all.rb
|
93
108
|
- lib/core_ext/modint.rb
|
94
109
|
- lib/crt.rb
|
95
110
|
- lib/dsu.rb
|
@@ -111,6 +126,7 @@ files:
|
|
111
126
|
- lib_helpers/ac-library-rb/all.rb
|
112
127
|
- lib_lock/ac-library-rb.rb
|
113
128
|
- lib_lock/ac-library-rb/convolution.rb
|
129
|
+
- lib_lock/ac-library-rb/core_ext/all.rb
|
114
130
|
- lib_lock/ac-library-rb/core_ext/modint.rb
|
115
131
|
- lib_lock/ac-library-rb/crt.rb
|
116
132
|
- lib_lock/ac-library-rb/dsu.rb
|
@@ -144,14 +160,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
160
|
requirements:
|
145
161
|
- - ">="
|
146
162
|
- !ruby/object:Gem::Version
|
147
|
-
version: 2.
|
163
|
+
version: 2.5.0
|
148
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
165
|
requirements:
|
150
166
|
- - ">="
|
151
167
|
- !ruby/object:Gem::Version
|
152
168
|
version: '0'
|
153
169
|
requirements: []
|
154
|
-
rubygems_version: 3.2.
|
170
|
+
rubygems_version: 3.2.15
|
155
171
|
signing_key:
|
156
172
|
specification_version: 4
|
157
173
|
summary: ac-library-rb is a ruby port of AtCoder Library (ACL).
|