ac-library-rb 0.5.3 → 0.5.4

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: cb356bb0c8bcb397f6422ce68964cfc7cdb3bda6915b91e1c57a20045e789407
4
- data.tar.gz: de638d458475278d7c34fe2a79633592e7c17325c27e6725b4a8a59f8049e7e9
3
+ metadata.gz: 7eb404ec2eab941e961da5a9cc0e19b87858a33101c791750a2e33d61781f8b8
4
+ data.tar.gz: a341ee2e478add1f3e611071213911dd919e7229ca3cc8cc9c19880e3e471467
5
5
  SHA512:
6
- metadata.gz: c2802262ebc08af6b69cd20c7f756aea82c17b3e5ed242e94d1b2f7934ee36a519375ef0f4a1eb2e2188b740ee7669e63755996c74984a69e9bd0417de3141f7
7
- data.tar.gz: 44dc88cad01600c5696b97230e332cf646a5d5c4e5cb2d73937eaae2d66008c43656284e702a523d152039ec7c53daf71ede355763bb9416339313cb356456ca
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 language Japanese version
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)
@@ -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
@@ -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
- **制約** `0 l n`
99
+ 以下の条件を両方満たす `r` (`l <= r <= n`)を(いずれか一つ)返します。
100
100
 
101
- **計算量** `O(log n)`
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
- **制約** `0 r n`
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
- **計算量** `O(log n)`
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に改造するだけでも解けます。
@@ -1,3 +1,3 @@
1
1
  module AcLibraryRb
2
- VERSION = "0.5.3".freeze
2
+ VERSION = "0.5.4".freeze
3
3
  end
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
@@ -41,6 +41,7 @@ class FenwickTree
41
41
  end
42
42
  res
43
43
  end
44
+ alias left_sum _sum
44
45
  end
45
46
 
46
47
  FeTree = FenwickTree
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 >= m
5
- res += (n - 1) * n / 2 * (a / m)
6
- a %= m
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 >= m
10
- res += n * (b / m)
11
- b %= m
12
+ if b < 0
13
+ b2 = b % m
14
+ res -= n * ((b2 - b) / m)
15
+ b = b2
12
16
  end
13
17
 
14
- y_max = a * n + b
15
- return res if y_max < m
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 SCCGraph
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 { |x, i| groups[x] << i }
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 = SCCGraph
76
- SCC = SCCGraph
77
- SCCG = SCCGraph
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
- 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
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
@@ -42,6 +42,7 @@ module AcLibraryRb
42
42
  end
43
43
  res
44
44
  end
45
+ alias left_sum _sum
45
46
  end
46
47
 
47
48
  FeTree = FenwickTree
@@ -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 >= m
6
- res += (n - 1) * n / 2 * (a / m)
7
- a %= m
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 >= m
11
- res += n * (b / m)
12
- b %= m
13
+ if b < 0
14
+ b2 = b % m
15
+ res -= n * ((b2 - b) / m)
16
+ b = b2
13
17
  end
14
18
 
15
- y_max = a * n + b
16
- return res if y_max < m
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 SCCGraph
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 { |x, i| groups[x] << i }
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 = SCCGraph
77
- SCC = SCCGraph
78
- SCCG = SCCGraph
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
- 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
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.3
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-05-22 00:00:00.000000000 Z
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.15
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).