ac-library-rb 0.5.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7eb404ec2eab941e961da5a9cc0e19b87858a33101c791750a2e33d61781f8b8
4
- data.tar.gz: a341ee2e478add1f3e611071213911dd919e7229ca3cc8cc9c19880e3e471467
3
+ metadata.gz: f191f90563fea038c7181e2bf9d13e1dc8caa0e816a364176e46b67c8d63f471
4
+ data.tar.gz: c89db082816046146cb60faa3747e046877394bfff776a3defe8063fb2d1c390
5
5
  SHA512:
6
- metadata.gz: 053064e9c40fe91e306a7695906bec15ef8752c3ddfa54f7954bf83f5954a626370f9390034f0777c0e403460f7ed650707a89be6a02d88c49cb52cdb0da5ffb
7
- data.tar.gz: 910dd3b9d493efba69cfe458a41a82c28ba4b5dde013521f56b29fbe7f3737d7d82fd50424b205c98683f0691da843de6ffc3ec58dd5cdf75e7d7ed1d94f1185
6
+ metadata.gz: '0114099d09f9566741d84ed2b5e43427b62592bb8b2a6b90d25b9f68288d2a387f34899351d18a7b3e0c93ec72af9cae4aac2f1d38f5fe517e30ec850e33429e'
7
+ data.tar.gz: cdb1eac1808855f86c00c991b4c66ae3489035420ef0fdb8c88915712ace8faa5db02da074a78734e0c4235058ac1e2a62a0fc9cc0523e6c85aff4617b47ae39
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "minitest"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "simplecov"
23
24
 
24
25
  # Specify which files should be added to the gem when it is released.
25
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
data/bin/lock_lib.rb CHANGED
@@ -17,7 +17,7 @@ Dir.glob(lib_path) do |file|
17
17
  end
18
18
 
19
19
  # copy library from `lib/core_ext` to `lib_lock/ac-library-rb/core_ext`
20
- ac_library_rb_classes = %w[ModInt]
20
+ ac_library_rb_classes = %w[ModInt FenwickTree PriorityQueue]
21
21
  replaces = ac_library_rb_classes.to_h{ |cls| ["#{cls}.new", "AcLibraryRb::#{cls}.new"] }
22
22
  pattern = Regexp.new(replaces.keys.join('|'))
23
23
 
data/document_en/dsu.md CHANGED
@@ -27,7 +27,7 @@ p d.size(2) # => 2
27
27
 
28
28
  ## Class Method
29
29
 
30
- ### new(n = 0) -> DSU
30
+ ### new(n) -> DSU
31
31
 
32
32
  ```rb
33
33
  d = DSU.new(n)
@@ -41,7 +41,7 @@ It creates an undirected graph with `n` vertices and `0` edges.
41
41
 
42
42
  **alias**
43
43
 
44
- - `DSU`, `DisjointSetUnion`, `UnionFind`, `UnionFindTree`
44
+ - `DSU`, `UnionFind`
45
45
 
46
46
  ## Instance Methods
47
47
 
@@ -5,7 +5,7 @@ Library for solving [Maximum flow problem](https://en.wikipedia.org/wiki/Maximum
5
5
 
6
6
  ## Class Methods.
7
7
 
8
- ### new(n = 0) -> MaxFlow
8
+ ### new(n) -> MaxFlow
9
9
 
10
10
  ```ruby
11
11
  graph = Maxflow.new(10)
@@ -4,7 +4,7 @@ It solves [Minimum\-cost flow problem](https://en.wikipedia.org/wiki/Minimum-cos
4
4
 
5
5
  ## Class Methods.
6
6
 
7
- ### new(n = 0) -> MinCostFlow
7
+ ### new(n) -> MinCostFlow
8
8
 
9
9
  ```ruby
10
10
  graph = MinCostFlow.new(10)
@@ -4,7 +4,8 @@ Segment Tree
4
4
 
5
5
  ## Class Methods
6
6
 
7
- ### new(n, e, &op) -> Segtree
7
+ ### new(n, e){ |x, y| ... } -> Segtree
8
+ ### new(n, op, e) -> Segtree
8
9
 
9
10
  ```rb
10
11
  seg = Segtree.new(n, e) { |x, y| ... }
@@ -15,7 +16,9 @@ It creates an array `a` of length `n`. All the elements are initialized to `e`.
15
16
  - `block`: returns `op(x, y)`
16
17
  - `e`: identity element.
17
18
 
18
- ### new(ary, e, &op) -> Segtree
19
+
20
+ ### new(ary, e){ |x, y| ... } -> Segtree
21
+ ### new(ary, op, e) -> Segtree
19
22
 
20
23
  ```rb
21
24
  seg = Segtree.new(ary, e) { |x, y| ... }
@@ -17,7 +17,7 @@ it decides whether there is a truth assignment that satisfies all clauses.
17
17
 
18
18
  ## Class Methods
19
19
 
20
- ### new(n = 0) -> TwoSAT
20
+ ### new(n) -> TwoSAT
21
21
 
22
22
  ```ruby
23
23
  ts = TwoSAT.new(n)
data/document_ja/dsu.md CHANGED
@@ -30,7 +30,7 @@ p d.size(2) # => 2
30
30
 
31
31
  ## 特異メソッド
32
32
 
33
- ### new(n = 0) -> DSU
33
+ ### new(n) -> DSU
34
34
 
35
35
  ```rb
36
36
  d = DSU.new(n)
@@ -48,9 +48,7 @@ d = DSU.new(n)
48
48
  **エイリアス**
49
49
 
50
50
  - `DSU`
51
- - `DisjointSetUnion`
52
51
  - `UnionFind`
53
- - `UnionFindTree`
54
52
 
55
53
  ## インスタンスメソッド
56
54
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 特異メソッド
6
6
 
7
- ### new(n = 0) -> MaxFlow
7
+ ### new(n) -> MaxFlow
8
8
 
9
9
  ```ruby
10
10
  graph = Maxflow.new(10)
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 特異メソッド
6
6
 
7
- ### new(n = 0) -> MinCostFlow
7
+ ### new(n) -> MinCostFlow
8
8
 
9
9
  ```ruby
10
10
  graph = MinCostFlow.new(10)
data/document_ja/scc.md CHANGED
@@ -6,7 +6,7 @@ Strongly Connected Components
6
6
 
7
7
  ## 特異メソッド
8
8
 
9
- ### new(n = 0) -> SCC
9
+ ### new(n) -> SCC
10
10
 
11
11
  ```ruby
12
12
  graph = SCC.new(6)
@@ -50,8 +50,9 @@ graph.scc
50
50
 
51
51
  ## Verified
52
52
 
53
- [ALPC: G \- SCC](https://atcoder.jp/contests/practice2/tasks/practice2_g)
54
- - [2538ms 2020/9/8](https://atcoder.jp/contests/practice2/submissions/16569175)
53
+ - [ALPC: G \- SCC](https://atcoder.jp/contests/practice2/tasks/practice2_g)
54
+ - [2538ms 2020/9/8](https://atcoder.jp/contests/practice2/submissions/16569175)
55
+ - [競プロ典型 90 問: 021 - Come Back in One Piece][https://atcoder.jp/contests/typical90/tasks/typical90_u]
55
56
 
56
57
  # 参考リンク
57
58
 
@@ -4,7 +4,8 @@
4
4
 
5
5
  ## 特異メソッド
6
6
 
7
- ### new(arg, e, &op) -> Segtree
7
+ ### new(arg, e){ |x, y| ... } -> Segtree
8
+ ### new(arg, op, e) -> Segtree
8
9
 
9
10
  ```rb
10
11
  seg = Segtree.new(arg, e) { |x, y| ... }
@@ -15,7 +15,7 @@
15
15
 
16
16
  ## 特異メソッド
17
17
 
18
- ### new(n = 0) -> TwoSAT
18
+ ### new(n) -> TwoSAT
19
19
 
20
20
  ```ruby
21
21
  ts = TwoSAT.new(n)
@@ -1,3 +1,3 @@
1
1
  module AcLibraryRb
2
- VERSION = "0.5.4".freeze
2
+ VERSION = "0.6.0".freeze
3
3
  end
data/lib/convolution.rb CHANGED
@@ -122,3 +122,24 @@ class Convolution
122
122
 
123
123
  private :batterfly, :batterfly_inv, :bsf, :calc_primitive_root
124
124
  end
125
+
126
+ # [EXPERIMENTAL]
127
+ def convolution(a, b, mod: 998244353, k: 35, z: 99)
128
+ n = a.size
129
+ m = b.size
130
+ return [] if n == 0 || m == 0
131
+
132
+ raise ArgumentError if a.min < 0 || b.min < 0
133
+
134
+ format = "%0#{k}x" # "%024x"
135
+ sa = ""
136
+ sb = ""
137
+ a.each{ |x| sa << (format % x) }
138
+ b.each{ |x| sb << (format % x) }
139
+
140
+ zero = '0'
141
+ s = zero * z + ("%x" % (sa.hex * sb.hex))
142
+ i = -(n + m - 1) * k - 1
143
+
144
+ Array.new(n + m - 1){ (s[i + 1..i += k] || zero).hex % mod }
145
+ end
@@ -0,0 +1,11 @@
1
+ class Array
2
+ def to_fenwick_tree
3
+ FenwickTree.new(self)
4
+ end
5
+ alias to_fetree to_fenwick_tree
6
+
7
+ def to_priority_queue
8
+ PriorityQueue.new(self)
9
+ end
10
+ alias to_pq to_priority_queue
11
+ end
data/lib/dsu.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # Disjoint Set Union
2
2
  class DSU
3
- def initialize(n = 0)
3
+ def initialize(n)
4
4
  @n = n
5
5
  @parent_or_size = Array.new(n, -1)
6
6
  # root node: -1 * component size
7
7
  # otherwise: parent
8
8
  end
9
9
 
10
- attr_accessor :parent_or_size
10
+ attr_reader :parent_or_size, :n
11
11
 
12
12
  def merge(a, b)
13
13
  x = leader(a)
@@ -27,7 +27,7 @@ class DSU
27
27
 
28
28
  def leader(a)
29
29
  unless 0 <= a && a < @n
30
- raise ArgumentError.new, "#{a} is out of range 0 <= arg < size"
30
+ raise ArgumentError.new, "#{a} is out of range (0...#{@n})"
31
31
  end
32
32
 
33
33
  @parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
@@ -44,6 +44,4 @@ class DSU
44
44
  end
45
45
  end
46
46
 
47
- UnionFind = DSU
48
- UnionFindTree = DSU
49
- DisjointSetUnion = DSU
47
+ UnionFind = DSU
data/lib/fenwick_tree.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  class FenwickTree
3
3
  attr_reader :data, :size
4
4
 
5
- def initialize(arg = 0)
5
+ def initialize(arg = nil)
6
6
  case arg
7
7
  when Array
8
8
  @size = arg.size
@@ -17,7 +17,7 @@ class FenwickTree
17
17
  @size = arg
18
18
  @data = Array.new(@size + 1, 0)
19
19
  else
20
- raise ArgumentError
20
+ raise ArgumentError.new("wrong argument. type is Array or Integer")
21
21
  end
22
22
  end
23
23
 
@@ -29,8 +29,25 @@ class FenwickTree
29
29
  end
30
30
  end
31
31
 
32
- def sum(l, r)
33
- _sum(r) - _sum(l)
32
+ # .sum(l, r) # [l, r) <- Original
33
+ # .sum(r) # [0, r) <- [Experimental]
34
+ # .sum(l..r) # [l, r] <- [Experimental]
35
+ def sum(a, b = nil)
36
+ if b
37
+ _sum(b) - _sum(a)
38
+ elsif a.is_a?(Range)
39
+ l = a.begin
40
+ l += @size if l < 0
41
+ if r = a.end
42
+ r += @size if r < 0
43
+ r += 1 unless a.exclude_end?
44
+ else
45
+ r = @size
46
+ end
47
+ _sum(r) - _sum(l)
48
+ else
49
+ _sum(a)
50
+ end
34
51
  end
35
52
 
36
53
  def _sum(i)
@@ -43,7 +60,3 @@ class FenwickTree
43
60
  end
44
61
  alias left_sum _sum
45
62
  end
46
-
47
- FeTree = FenwickTree
48
- Fetree = FenwickTree
49
- BinaryIndexedTree = FenwickTree
data/lib/lazy_segtree.rb CHANGED
@@ -49,7 +49,18 @@ class LazySegtree
49
49
  end
50
50
  alias [] get
51
51
 
52
- def prod(l, r)
52
+ def prod(l, r = nil)
53
+ if r.nil? # if 1st argument l is Range
54
+ if r = l.end
55
+ r += @n if r < 0
56
+ r += 1 unless l.exclude_end?
57
+ else
58
+ r = @n
59
+ end
60
+ l = l.begin
61
+ l += @n if l < 0
62
+ end
63
+
53
64
  return @e if l == r
54
65
 
55
66
  l += @size
@@ -83,9 +94,22 @@ class LazySegtree
83
94
  end
84
95
 
85
96
  # apply(pos, f)
86
- # apply(l, r, f) -> range_apply(l, r, f)
97
+ # apply(l, r, f) -> range_apply(l, r, f)
98
+ # apply(l...r, f) -> range_apply(l, r, f) ... [Experimental]
87
99
  def apply(pos, f, fr = nil)
88
- return range_apply(pos, f, fr) if fr
100
+ if fr
101
+ return range_apply(pos, f, fr)
102
+ elsif pos.is_a?(Range)
103
+ l = pos.begin
104
+ l += @n if l < 0
105
+ if r = pos.end
106
+ r += @n if r < 0
107
+ r += 1 unless pos.exclude_end?
108
+ else
109
+ r = @n
110
+ end
111
+ return range_apply(l, r, f)
112
+ end
89
113
 
90
114
  pos += @size
91
115
  @log.downto(1) { |i| push(pos >> i) }
@@ -194,3 +218,5 @@ class LazySegtree
194
218
  @lz[k] = @id
195
219
  end
196
220
  end
221
+
222
+ LazySegTree = LazySegtree
data/lib/max_flow.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MaxFlowGraph
2
2
  class MaxFlow
3
- def initialize(n = 0)
3
+ def initialize(n)
4
4
  @n = n
5
5
  @pos = []
6
6
  @g = Array.new(n) { [] }
@@ -20,6 +20,15 @@ class MaxFlow
20
20
  edge_number
21
21
  end
22
22
 
23
+ def add_edges(edges)
24
+ edges.each{ |from, to, cap| add_edge(from, to, cap) }
25
+ self
26
+ end
27
+
28
+ def add(x, to = nil, cap = nil)
29
+ cap ? add_edge(x, to, cap) : add_edges(x)
30
+ end
31
+
23
32
  def push(edge)
24
33
  add_edge(*edge)
25
34
  end
@@ -132,6 +141,3 @@ class MaxFlow
132
141
  res
133
142
  end
134
143
  end
135
-
136
- MaxFlowGraph = MaxFlow
137
- MFGraph = MaxFlow
data/lib/min_cost_flow.rb CHANGED
@@ -11,7 +11,7 @@ class MinCostFlow
11
11
  @g_cost = Array.new(n) { [] }
12
12
  @pv = Array.new(n)
13
13
  @pe = Array.new(n)
14
- @dual = Array.new(n) { 0 }
14
+ @dual = Array.new(n, 0)
15
15
  end
16
16
 
17
17
  def add_edge(from, to, cap, cost)
@@ -36,6 +36,15 @@ class MinCostFlow
36
36
  edge_number
37
37
  end
38
38
 
39
+ def add_edges(edges)
40
+ edges.each{ |from, to, cap, cost| add_edge(from, to, cap, cost) }
41
+ self
42
+ end
43
+
44
+ def add(x, to = nil, cap = nil, cost = nil)
45
+ cost ? add_edge(x, to, cap, cost) : add_edges(x)
46
+ end
47
+
39
48
  def get_edge(i)
40
49
  from, id = @pos[i]
41
50
  to = @g_to[from][id]
@@ -138,6 +147,3 @@ class MinCostFlow
138
147
  end
139
148
  alias min_cost_slop slope
140
149
  end
141
-
142
- MCF = MinCostFlow
143
- MCFGraph = MinCostFlow
data/lib/scc.rb CHANGED
@@ -1,18 +1,31 @@
1
1
  # Strongly Connected Components
2
2
  class SCC
3
3
  # initialize graph with n vertices
4
- def initialize(n = 0)
5
- @n, @edges = n, []
4
+ def initialize(n)
5
+ @n = n
6
+ @edges = []
6
7
  end
7
8
 
8
9
  # add directed edge
9
10
  def add_edge(from, to)
10
- raise "invalid params" unless (0...@n).include? from and (0...@n).include? to
11
+ unless 0 <= from && from < @n and 0 <= to && to < @n
12
+ msg = "Wrong params: from=#{from} and to=#{to} must be in 0...#{@n}"
13
+ raise ArgumentError.new(msg)
14
+ end
11
15
 
12
16
  @edges << [from, to]
13
17
  self
14
18
  end
15
19
 
20
+ def add_edges(edges)
21
+ edges.each{ |from, to| add_edge(from, to) }
22
+ self
23
+ end
24
+
25
+ def add(x, to = nil)
26
+ to ? add_edge(x, to) : add_edges(x)
27
+ end
28
+
16
29
  # returns list of strongly connected components
17
30
  # the components are sorted in topological order
18
31
  # O(@n + @edges.size)
@@ -58,7 +71,8 @@ class SCC
58
71
  end
59
72
 
60
73
  def csr
61
- start, elist = [0] * (@n + 1), [nil] * @edges.size
74
+ start = [0] * (@n + 1)
75
+ elist = [nil] * @edges.size
62
76
  @edges.each { |(i, _)| start[i + 1] += 1 }
63
77
  @n.times { |i| start[i + 1] += start[i] }
64
78
  counter = start.dup
@@ -69,8 +83,3 @@ class SCC
69
83
  [start, elist]
70
84
  end
71
85
  end
72
-
73
- # class alias
74
- StronglyConnectedComponents = SCC
75
- SCCGraph = SCC
76
- SCCG = SCC
data/lib/segtree.rb CHANGED
@@ -2,14 +2,10 @@
2
2
  class Segtree
3
3
  attr_reader :d, :op, :n, :leaf_size, :log
4
4
 
5
- # new(e){ |x, y| }
6
5
  # new(v, e){ |x, y| }
7
6
  # new(v, op, e)
8
- def initialize(a0, a1 = nil, a2 = nil, &block)
9
- if a1.nil?
10
- @e, @op = a0, proc(&block)
11
- v = []
12
- elsif a2.nil?
7
+ def initialize(a0, a1, a2 = nil, &block)
8
+ if a2.nil?
13
9
  @e, @op = a1, proc(&block)
14
10
  v = (a0.is_a?(Array) ? a0 : [@e] * a0)
15
11
  else
@@ -37,7 +33,18 @@ class Segtree
37
33
  end
38
34
  alias [] get
39
35
 
40
- def prod(l, r)
36
+ def prod(l, r = nil)
37
+ if r.nil? # if 1st argument l is Range
38
+ if r = l.end
39
+ r += @n if r < 0
40
+ r += 1 unless l.exclude_end?
41
+ else
42
+ r = @n
43
+ end
44
+ l = l.begin
45
+ l += @n if l < 0
46
+ end
47
+
41
48
  return @e if l == r
42
49
 
43
50
  sml = @e
@@ -129,7 +136,7 @@ class Segtree
129
136
 
130
137
  # def inspect # for debug
131
138
  # t = 0
132
- # res = "SegmentTree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
139
+ # res = "Segtree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
133
140
  # a = @d[1, @d.size - 1]
134
141
  # a.each_with_index do |e, i|
135
142
  # res << e.to_s << ' '
@@ -142,5 +149,4 @@ class Segtree
142
149
  # end
143
150
  end
144
151
 
145
- SegTree = Segtree
146
- SegmentTree = Segtree
152
+ SegTree = Segtree
data/lib/two_sat.rb CHANGED
@@ -3,16 +3,18 @@ require_relative './scc.rb'
3
3
  # TwoSAT
4
4
  # Reference: https://github.com/atcoder/ac-library/blob/master/atcoder/twosat.hpp
5
5
  class TwoSAT
6
- def initialize(n = 0)
6
+ def initialize(n)
7
7
  @n = n
8
8
  @answer = Array.new(n)
9
- @scc = SCCGraph.new(2 * n)
9
+ @scc = SCC.new(2 * n)
10
10
  end
11
11
 
12
12
  attr_reader :answer
13
13
 
14
14
  def add_clause(i, f, j, g)
15
- raise RangeError unless (0...@n).cover?(i) && (0...@n).cover?(j)
15
+ unless 0 <= i && i < @n and 0 <= j && j < @n
16
+ raise RangeError.new
17
+ end
16
18
 
17
19
  @scc.add_edge(2 * i + (f ? 0 : 1), 2 * j + (g ? 1 : 0))
18
20
  @scc.add_edge(2 * j + (g ? 0 : 1), 2 * i + (f ? 1 : 0))
@@ -2,6 +2,8 @@ module AcLibraryRb
2
2
  end
3
3
  include AcLibraryRb
4
4
 
5
+ require_relative './lib_lock/ac-library-rb/all.rb'
6
+
5
7
  require_relative './ac-library-rb/convolution'
6
8
  require_relative './ac-library-rb/crt'
7
9
  require_relative './ac-library-rb/dsu'
@@ -123,4 +123,25 @@ module AcLibraryRb
123
123
 
124
124
  private :batterfly, :batterfly_inv, :bsf, :calc_primitive_root
125
125
  end
126
+
127
+ # [EXPERIMENTAL]
128
+ def convolution(a, b, mod: 998244353, k: 35, z: 99)
129
+ n = a.size
130
+ m = b.size
131
+ return [] if n == 0 || m == 0
132
+
133
+ raise ArgumentError if a.min < 0 || b.min < 0
134
+
135
+ format = "%0#{k}x" # "%024x"
136
+ sa = ""
137
+ sb = ""
138
+ a.each{ |x| sa << (format % x) }
139
+ b.each{ |x| sb << (format % x) }
140
+
141
+ zero = '0'
142
+ s = zero * z + ("%x" % (sa.hex * sb.hex))
143
+ i = -(n + m - 1) * k - 1
144
+
145
+ Array.new(n + m - 1){ (s[i + 1..i += k] || zero).hex % mod }
146
+ end
126
147
  end
@@ -0,0 +1,11 @@
1
+ class Array
2
+ def to_fenwick_tree
3
+ AcLibraryRb::FenwickTree.new(self)
4
+ end
5
+ alias to_fetree to_fenwick_tree
6
+
7
+ def to_priority_queue
8
+ AcLibraryRb::PriorityQueue.new(self)
9
+ end
10
+ alias to_pq to_priority_queue
11
+ end
@@ -1,14 +1,14 @@
1
1
  module AcLibraryRb
2
2
  # Disjoint Set Union
3
3
  class DSU
4
- def initialize(n = 0)
4
+ def initialize(n)
5
5
  @n = n
6
6
  @parent_or_size = Array.new(n, -1)
7
7
  # root node: -1 * component size
8
8
  # otherwise: parent
9
9
  end
10
10
 
11
- attr_accessor :parent_or_size
11
+ attr_reader :parent_or_size, :n
12
12
 
13
13
  def merge(a, b)
14
14
  x = leader(a)
@@ -28,7 +28,7 @@ module AcLibraryRb
28
28
 
29
29
  def leader(a)
30
30
  unless 0 <= a && a < @n
31
- raise ArgumentError.new, "#{a} is out of range 0 <= arg < size"
31
+ raise ArgumentError.new, "#{a} is out of range (0...#{@n})"
32
32
  end
33
33
 
34
34
  @parent_or_size[a] < 0 ? a : (@parent_or_size[a] = leader(@parent_or_size[a]))
@@ -45,7 +45,5 @@ module AcLibraryRb
45
45
  end
46
46
  end
47
47
 
48
- UnionFind = DSU
49
- UnionFindTree = DSU
50
- DisjointSetUnion = DSU
48
+ UnionFind = DSU
51
49
  end
@@ -3,7 +3,7 @@ module AcLibraryRb
3
3
  class FenwickTree
4
4
  attr_reader :data, :size
5
5
 
6
- def initialize(arg = 0)
6
+ def initialize(arg = nil)
7
7
  case arg
8
8
  when Array
9
9
  @size = arg.size
@@ -18,7 +18,7 @@ module AcLibraryRb
18
18
  @size = arg
19
19
  @data = Array.new(@size + 1, 0)
20
20
  else
21
- raise ArgumentError
21
+ raise ArgumentError.new("wrong argument. type is Array or Integer")
22
22
  end
23
23
  end
24
24
 
@@ -30,8 +30,25 @@ module AcLibraryRb
30
30
  end
31
31
  end
32
32
 
33
- def sum(l, r)
34
- _sum(r) - _sum(l)
33
+ # .sum(l, r) # [l, r) <- Original
34
+ # .sum(r) # [0, r) <- [Experimental]
35
+ # .sum(l..r) # [l, r] <- [Experimental]
36
+ def sum(a, b = nil)
37
+ if b
38
+ _sum(b) - _sum(a)
39
+ elsif a.is_a?(Range)
40
+ l = a.begin
41
+ l += @size if l < 0
42
+ if r = a.end
43
+ r += @size if r < 0
44
+ r += 1 unless a.exclude_end?
45
+ else
46
+ r = @size
47
+ end
48
+ _sum(r) - _sum(l)
49
+ else
50
+ _sum(a)
51
+ end
35
52
  end
36
53
 
37
54
  def _sum(i)
@@ -44,8 +61,4 @@ module AcLibraryRb
44
61
  end
45
62
  alias left_sum _sum
46
63
  end
47
-
48
- FeTree = FenwickTree
49
- Fetree = FenwickTree
50
- BinaryIndexedTree = FenwickTree
51
64
  end
@@ -50,7 +50,18 @@ module AcLibraryRb
50
50
  end
51
51
  alias [] get
52
52
 
53
- def prod(l, r)
53
+ def prod(l, r = nil)
54
+ if r.nil? # if 1st argument l is Range
55
+ if r = l.end
56
+ r += @n if r < 0
57
+ r += 1 unless l.exclude_end?
58
+ else
59
+ r = @n
60
+ end
61
+ l = l.begin
62
+ l += @n if l < 0
63
+ end
64
+
54
65
  return @e if l == r
55
66
 
56
67
  l += @size
@@ -84,9 +95,22 @@ module AcLibraryRb
84
95
  end
85
96
 
86
97
  # apply(pos, f)
87
- # apply(l, r, f) -> range_apply(l, r, f)
98
+ # apply(l, r, f) -> range_apply(l, r, f)
99
+ # apply(l...r, f) -> range_apply(l, r, f) ... [Experimental]
88
100
  def apply(pos, f, fr = nil)
89
- return range_apply(pos, f, fr) if fr
101
+ if fr
102
+ return range_apply(pos, f, fr)
103
+ elsif pos.is_a?(Range)
104
+ l = pos.begin
105
+ l += @n if l < 0
106
+ if r = pos.end
107
+ r += @n if r < 0
108
+ r += 1 unless pos.exclude_end?
109
+ else
110
+ r = @n
111
+ end
112
+ return range_apply(l, r, f)
113
+ end
90
114
 
91
115
  pos += @size
92
116
  @log.downto(1) { |i| push(pos >> i) }
@@ -195,4 +219,6 @@ module AcLibraryRb
195
219
  @lz[k] = @id
196
220
  end
197
221
  end
222
+
223
+ LazySegTree = LazySegtree
198
224
  end
@@ -1,7 +1,7 @@
1
1
  module AcLibraryRb
2
2
  # MaxFlowGraph
3
3
  class MaxFlow
4
- def initialize(n = 0)
4
+ def initialize(n)
5
5
  @n = n
6
6
  @pos = []
7
7
  @g = Array.new(n) { [] }
@@ -21,6 +21,15 @@ module AcLibraryRb
21
21
  edge_number
22
22
  end
23
23
 
24
+ def add_edges(edges)
25
+ edges.each{ |from, to, cap| add_edge(from, to, cap) }
26
+ self
27
+ end
28
+
29
+ def add(x, to = nil, cap = nil)
30
+ cap ? add_edge(x, to, cap) : add_edges(x)
31
+ end
32
+
24
33
  def push(edge)
25
34
  add_edge(*edge)
26
35
  end
@@ -133,7 +142,4 @@ module AcLibraryRb
133
142
  res
134
143
  end
135
144
  end
136
-
137
- MaxFlowGraph = MaxFlow
138
- MFGraph = MaxFlow
139
145
  end
@@ -12,7 +12,7 @@ module AcLibraryRb
12
12
  @g_cost = Array.new(n) { [] }
13
13
  @pv = Array.new(n)
14
14
  @pe = Array.new(n)
15
- @dual = Array.new(n) { 0 }
15
+ @dual = Array.new(n, 0)
16
16
  end
17
17
 
18
18
  def add_edge(from, to, cap, cost)
@@ -37,6 +37,15 @@ module AcLibraryRb
37
37
  edge_number
38
38
  end
39
39
 
40
+ def add_edges(edges)
41
+ edges.each{ |from, to, cap, cost| add_edge(from, to, cap, cost) }
42
+ self
43
+ end
44
+
45
+ def add(x, to = nil, cap = nil, cost = nil)
46
+ cost ? add_edge(x, to, cap, cost) : add_edges(x)
47
+ end
48
+
40
49
  def get_edge(i)
41
50
  from, id = @pos[i]
42
51
  to = @g_to[from][id]
@@ -139,7 +148,4 @@ module AcLibraryRb
139
148
  end
140
149
  alias min_cost_slop slope
141
150
  end
142
-
143
- MCF = MinCostFlow
144
- MCFGraph = MinCostFlow
145
151
  end
@@ -2,18 +2,31 @@ module AcLibraryRb
2
2
  # Strongly Connected Components
3
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]
14
18
  self
15
19
  end
16
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)
28
+ end
29
+
17
30
  # returns list of strongly connected components
18
31
  # the components are sorted in topological order
19
32
  # O(@n + @edges.size)
@@ -59,7 +72,8 @@ module AcLibraryRb
59
72
  end
60
73
 
61
74
  def csr
62
- start, elist = [0] * (@n + 1), [nil] * @edges.size
75
+ start = [0] * (@n + 1)
76
+ elist = [nil] * @edges.size
63
77
  @edges.each { |(i, _)| start[i + 1] += 1 }
64
78
  @n.times { |i| start[i + 1] += start[i] }
65
79
  counter = start.dup
@@ -70,9 +84,4 @@ module AcLibraryRb
70
84
  [start, elist]
71
85
  end
72
86
  end
73
-
74
- # class alias
75
- StronglyConnectedComponents = SCC
76
- SCCGraph = SCC
77
- SCCG = SCC
78
87
  end
@@ -3,14 +3,10 @@ module AcLibraryRb
3
3
  class Segtree
4
4
  attr_reader :d, :op, :n, :leaf_size, :log
5
5
 
6
- # new(e){ |x, y| }
7
6
  # new(v, e){ |x, y| }
8
7
  # new(v, op, e)
9
- def initialize(a0, a1 = nil, a2 = nil, &block)
10
- if a1.nil?
11
- @e, @op = a0, proc(&block)
12
- v = []
13
- elsif a2.nil?
8
+ def initialize(a0, a1, a2 = nil, &block)
9
+ if a2.nil?
14
10
  @e, @op = a1, proc(&block)
15
11
  v = (a0.is_a?(Array) ? a0 : [@e] * a0)
16
12
  else
@@ -38,7 +34,18 @@ module AcLibraryRb
38
34
  end
39
35
  alias [] get
40
36
 
41
- def prod(l, r)
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
48
+
42
49
  return @e if l == r
43
50
 
44
51
  sml = @e
@@ -130,7 +137,7 @@ module AcLibraryRb
130
137
 
131
138
  # def inspect # for debug
132
139
  # t = 0
133
- # res = "SegmentTree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
140
+ # res = "Segtree @e = #{@e}, @n = #{@n}, @leaf_size = #{@leaf_size} @op = #{@op}\n "
134
141
  # a = @d[1, @d.size - 1]
135
142
  # a.each_with_index do |e, i|
136
143
  # res << e.to_s << ' '
@@ -143,6 +150,5 @@ module AcLibraryRb
143
150
  # end
144
151
  end
145
152
 
146
- SegTree = Segtree
147
- SegmentTree = Segtree
153
+ SegTree = Segtree
148
154
  end
@@ -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.4
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-06-06 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
@@ -151,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
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).