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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -0
  3. data/README.ja.md +102 -4
  4. data/README.md +73 -1
  5. data/Rakefile +2 -1
  6. data/ac-library-rb.gemspec +3 -2
  7. data/bin/lock_lib.rb +13 -7
  8. data/document_en/dsu.md +2 -2
  9. data/document_en/lazy_segtree.md +20 -4
  10. data/document_en/max_flow.md +1 -1
  11. data/document_en/min_cost_flow.md +1 -1
  12. data/document_en/segtree.md +36 -3
  13. data/document_en/two_sat.md +1 -1
  14. data/document_ja/dsu.md +1 -3
  15. data/document_ja/lazy_segtree.md +63 -19
  16. data/document_ja/max_flow.md +1 -1
  17. data/document_ja/min_cost_flow.md +1 -1
  18. data/document_ja/scc.md +4 -3
  19. data/document_ja/segtree.md +49 -8
  20. data/document_ja/two_sat.md +1 -1
  21. data/lib/ac-library-rb/version.rb +1 -1
  22. data/lib/convolution.rb +21 -0
  23. data/lib/core_ext/all.rb +11 -0
  24. data/lib/dsu.rb +9 -6
  25. data/lib/fenwick_tree.rb +22 -8
  26. data/lib/floor_sum.rb +33 -10
  27. data/lib/lazy_segtree.rb +83 -10
  28. data/lib/max_flow.rb +10 -4
  29. data/lib/min_cost_flow.rb +13 -7
  30. data/lib/modint.rb +3 -1
  31. data/lib/scc.rb +21 -13
  32. data/lib/segtree.rb +38 -26
  33. data/lib/suffix_array.rb +8 -8
  34. data/lib/two_sat.rb +5 -3
  35. data/lib_lock/ac-library-rb.rb +2 -0
  36. data/lib_lock/ac-library-rb/convolution.rb +21 -0
  37. data/lib_lock/ac-library-rb/core_ext/all.rb +11 -0
  38. data/lib_lock/ac-library-rb/core_ext/modint.rb +3 -3
  39. data/lib_lock/ac-library-rb/dsu.rb +9 -6
  40. data/lib_lock/ac-library-rb/fenwick_tree.rb +22 -8
  41. data/lib_lock/ac-library-rb/floor_sum.rb +33 -10
  42. data/lib_lock/ac-library-rb/lazy_segtree.rb +83 -10
  43. data/lib_lock/ac-library-rb/max_flow.rb +10 -4
  44. data/lib_lock/ac-library-rb/min_cost_flow.rb +13 -7
  45. data/lib_lock/ac-library-rb/modint.rb +3 -1
  46. data/lib_lock/ac-library-rb/scc.rb +21 -13
  47. data/lib_lock/ac-library-rb/segtree.rb +38 -26
  48. data/lib_lock/ac-library-rb/suffix_array.rb +8 -8
  49. data/lib_lock/ac-library-rb/two_sat.rb +5 -3
  50. metadata +20 -4
@@ -162,7 +162,9 @@ module AcLibraryRb
162
162
 
163
163
  def inv_internal(a)
164
164
  if $_mod_is_prime
165
- a != 0 ? a.pow($_mod - 2, $_mod) : raise(RangeError, 'no inverse')
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 SCCGraph
3
+ class SCC
4
4
  # initialize graph with n vertices
5
- def initialize(n = 0)
6
- @n, @edges = 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
- raise "invalid params" unless (0...@n).include? from and (0...@n).include? to
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 { |x, i| groups[x] << i }
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, elist = [0] * (@n + 1), [nil] * @edges.size
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
- def initialize(arg = 0, e, &block)
7
- case arg
8
- when Integer
9
- v = Array.new(arg) { e }
10
- when Array
11
- v = arg
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) { e }
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
- t = 0
127
- res = "SegmentTree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
128
- a = @d[1, @d.size - 1]
129
- a.each_with_index do |e, i|
130
- res << e.to_s << ' '
131
- if t == i && i < @leaf_size
132
- res << "\n "
133
- t = t * 2 + 2
134
- end
135
- end
136
- res
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 = 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 != end_r - r
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 not upper
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 = 0)
7
+ def initialize(n)
8
8
  @n = n
9
9
  @answer = Array.new(n)
10
- @scc = SCCGraph.new(2 * n)
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
- raise RangeError unless (0...@n).cover?(i) && (0...@n).cover?(j)
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.5.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-05-16 00:00:00.000000000 Z
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.3.0
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.11
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).