ac-library-rb 0.5.3 → 0.5.4

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