ac-library-rb 0.5.0 → 0.6.0

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