ac-library-rb 1.0.0 → 1.2.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 +4 -4
- data/.github/workflows/unittest.yml +1 -1
- data/.rubocop.yml +3 -0
- data/README.ja.md +2 -2
- data/README.md +3 -3
- data/document_en/dsu.md +2 -2
- data/document_en/fenwick_tree.md +2 -2
- data/document_en/index.md +54 -54
- data/document_en/lazy_segtree.md +2 -2
- data/document_en/math.md +8 -8
- data/document_en/max_flow.md +2 -2
- data/document_en/min_cost_flow.md +2 -2
- data/document_en/modint.md +3 -3
- data/document_en/priority_queue.md +1 -1
- data/document_en/scc.md +2 -2
- data/document_en/segtree.md +2 -2
- data/document_ja/dsu.md +2 -2
- data/document_ja/index.md +54 -54
- data/document_ja/lazy_segtree.md +2 -2
- data/document_ja/math.md +8 -8
- data/document_ja/max_flow.md +2 -2
- data/document_ja/min_cost_flow.md +2 -2
- data/document_ja/modint.md +3 -3
- data/document_ja/priority_queue.md +1 -1
- data/document_ja/scc.md +2 -2
- data/document_ja/segtree.md +2 -2
- data/lib/ac-library-rb/version.rb +1 -1
- data/lib/core_ext/integer.rb +31 -0
- data/lib/deque.rb +306 -0
- data/lib/modint.rb +12 -0
- data/lib/priority_queue.rb +10 -1
- data/lib_helpers/ac-library-rb/all.rb +1 -0
- data/lib_helpers/ac-library-rb.rb +1 -0
- data/lib_lock/ac-library-rb/core_ext/integer.rb +31 -0
- data/lib_lock/ac-library-rb/deque.rb +308 -0
- data/lib_lock/ac-library-rb/modint.rb +12 -0
- data/lib_lock/ac-library-rb/priority_queue.rb +10 -1
- metadata +6 -2
@@ -79,8 +79,8 @@ graph.edges
|
|
79
79
|
## 参考リンク
|
80
80
|
|
81
81
|
- 当ライブラリ
|
82
|
-
- [当ライブラリの実装コード min_cost_flow.rb](https://github.com/universato/ac-library-rb/blob/
|
83
|
-
- [当ライブラリのテストコード min_cost_flow_test.rb](https://github.com/universato/ac-library-rb/blob/
|
82
|
+
- [当ライブラリの実装コード min_cost_flow.rb](https://github.com/universato/ac-library-rb/blob/main/lib/min_cost_flow.rb)
|
83
|
+
- [当ライブラリのテストコード min_cost_flow_test.rb](https://github.com/universato/ac-library-rb/blob/main/test/min_cost_flow_test.rb)
|
84
84
|
- 本家ライブラリ
|
85
85
|
- [本家ライブラリのドキュメント mincostflow.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/mincostflow.md)
|
86
86
|
- [本家ライブラリの実装コード mincostflow.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/mincostflow.hpp)
|
data/document_ja/modint.md
CHANGED
@@ -212,8 +212,8 @@ p 12.to_m == 1 #=> true
|
|
212
212
|
## 参考リンク
|
213
213
|
|
214
214
|
- 当ライブラリ
|
215
|
-
- [当ライブラリのコード modint.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/
|
216
|
-
- [当ライブラリのコード modint_test.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/
|
215
|
+
- [当ライブラリのコード modint.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/main/lib/modint.rb)
|
216
|
+
- [当ライブラリのコード modint_test.rb(GitHub)](https://github.com/universato/ac-library-rb/blob/main/lib/modint.rb)
|
217
217
|
- 本家ライブラリ
|
218
218
|
- [本家の実装コード modint.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/modint.hpp)
|
219
219
|
- [本家のテストコード modint_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/modint.hpp)
|
@@ -223,7 +223,7 @@ p 12.to_m == 1 #=> true
|
|
223
223
|
- その他
|
224
224
|
- [modint 構造体を使ってみませんか? \(C\+\+\) - noshi91のメモ](https://noshi91.hatenablog.com/entry/2019/03/31/174006)(2019/3/31)
|
225
225
|
- [Pythonでmodintを実装してみた - Qiita](https://qiita.com/wotsushi/items/c936838df992b706084c)(2019/4/1)
|
226
|
-
- [C#版のModIntのドキュメント](https://github.com/key-moon/ac-library-cs/blob/
|
226
|
+
- [C#版のModIntのドキュメント](https://github.com/key-moon/ac-library-cs/blob/main/document_ja/modint.md)
|
227
227
|
|
228
228
|
|
229
229
|
## Q&A
|
data/document_ja/scc.md
CHANGED
@@ -58,8 +58,8 @@ graph.scc
|
|
58
58
|
# 参考リンク
|
59
59
|
|
60
60
|
- 当ライブラリ
|
61
|
-
- [当ライブラリの実装コード scc.rb](https://github.com/universato/ac-library-rb/blob/
|
62
|
-
- [当ライブラリの実装コード scc_test.rb](https://github.com/universato/ac-library-rb/blob/
|
61
|
+
- [当ライブラリの実装コード scc.rb](https://github.com/universato/ac-library-rb/blob/main/lib/scc.rb)
|
62
|
+
- [当ライブラリの実装コード scc_test.rb](https://github.com/universato/ac-library-rb/blob/main/test/scc_test.rb)
|
63
63
|
- 本家ライブラリ
|
64
64
|
- [本家ライブラリの実装コード scc.hpp](https://github.com/atcoder/ac-library/blob/master/atcoder/scc.hpp)
|
65
65
|
- [本家ライブラリのドキュメント scc.md](https://github.com/atcoder/ac-library/blob/master/document_ja/scc.md)
|
data/document_ja/segtree.md
CHANGED
@@ -153,8 +153,8 @@ Segtree上で`0 <= l <= r`の範囲で、`f(prod(l, r))`の結果を二分探索
|
|
153
153
|
## 参考リンク
|
154
154
|
|
155
155
|
- 当ライブラリ
|
156
|
-
- [当ライブラリの実装コード segtree.rb](https://github.com/universato/ac-library-rb/blob/
|
157
|
-
- [当ライブラリのテストコード segtree.rb](https://github.com/universato/ac-library-rb/blob/
|
156
|
+
- [当ライブラリの実装コード segtree.rb](https://github.com/universato/ac-library-rb/blob/main/lib/segtree.rb)
|
157
|
+
- [当ライブラリのテストコード segtree.rb](https://github.com/universato/ac-library-rb/blob/main/test/segtree_test.rb)
|
158
158
|
- テストコードも具体的な使い方として役に立つかもしれまん。
|
159
159
|
- 本家ライブラリ
|
160
160
|
- [本家ライブラリのドキュメント segtree.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/segtree.md)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "prime"
|
2
|
+
|
3
|
+
class Integer
|
4
|
+
# Returns the positive divisors of +self+ if +self+ is positive.
|
5
|
+
#
|
6
|
+
# == Example
|
7
|
+
# 6.divisors #=> [1, 2, 3, 6]
|
8
|
+
# 7.divisors #=> [1, 7]
|
9
|
+
# 8.divisors #=> [1, 2, 4, 8]
|
10
|
+
def divisors
|
11
|
+
if prime?
|
12
|
+
[1, self]
|
13
|
+
elsif self == 1
|
14
|
+
[1]
|
15
|
+
else
|
16
|
+
xs = prime_division.map{ |p, n| Array.new(n + 1){ |e| p**e } }
|
17
|
+
x = xs.pop
|
18
|
+
x.product(*xs).map{ |t| t.inject(:*) }.sort
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Iterates the given block for each divisor of +self+.
|
23
|
+
#
|
24
|
+
# == Example
|
25
|
+
# ds = []
|
26
|
+
# 10.divisors{ |d| ds << d }
|
27
|
+
# ds #=> [1, 2, 5, 10]
|
28
|
+
def each_divisor(&block)
|
29
|
+
block_given? ? divisors.each(&block) : enum_for(:each_divisor)
|
30
|
+
end
|
31
|
+
end
|
data/lib/deque.rb
ADDED
@@ -0,0 +1,306 @@
|
|
1
|
+
class Deque
|
2
|
+
include Enumerable
|
3
|
+
|
4
|
+
def self.[](*args)
|
5
|
+
new(args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(arg = [], value = nil, initial_capacity: 0)
|
9
|
+
ary = arg
|
10
|
+
ary = Array.new(arg, value) if arg.is_a?(Integer)
|
11
|
+
@n = [initial_capacity, ary.size].max + 1
|
12
|
+
@buf = ary + [nil] * (@n - ary.size)
|
13
|
+
@head = 0
|
14
|
+
@tail = ary.size
|
15
|
+
@reverse_count = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def empty?
|
19
|
+
size == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def size
|
23
|
+
(@tail - @head) % @n
|
24
|
+
end
|
25
|
+
alias length size
|
26
|
+
|
27
|
+
def <<(x)
|
28
|
+
reversed? ? __unshift(x) : __push(x)
|
29
|
+
end
|
30
|
+
|
31
|
+
def push(*args)
|
32
|
+
args.each{ |x| self << x }
|
33
|
+
self
|
34
|
+
end
|
35
|
+
alias append push
|
36
|
+
|
37
|
+
def unshift(*args)
|
38
|
+
if reversed?
|
39
|
+
args.reverse_each{ |e| __push(e) }
|
40
|
+
else
|
41
|
+
args.reverse_each{ |e| __unshift(e) }
|
42
|
+
end
|
43
|
+
self
|
44
|
+
end
|
45
|
+
alias prepend unshift
|
46
|
+
|
47
|
+
def pop
|
48
|
+
reversed? ? __shift : __pop
|
49
|
+
end
|
50
|
+
|
51
|
+
def shift
|
52
|
+
reversed? ? __pop : __shift
|
53
|
+
end
|
54
|
+
|
55
|
+
def last
|
56
|
+
self[-1]
|
57
|
+
end
|
58
|
+
|
59
|
+
def slice(idx)
|
60
|
+
sz = size
|
61
|
+
return nil if idx < -sz || sz <= idx
|
62
|
+
|
63
|
+
@buf[__index(idx)]
|
64
|
+
end
|
65
|
+
|
66
|
+
def [](a, b = nil)
|
67
|
+
if b
|
68
|
+
slice2(a, b)
|
69
|
+
elsif a.is_a?(Range)
|
70
|
+
s = a.begin
|
71
|
+
t = a.end
|
72
|
+
t -= 1 if a.exclude_end?
|
73
|
+
slice2(s, t - s + 1)
|
74
|
+
else
|
75
|
+
slice1(a)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def at(idx)
|
80
|
+
slice1(idx)
|
81
|
+
end
|
82
|
+
|
83
|
+
private def slice1(idx)
|
84
|
+
sz = size
|
85
|
+
return nil if idx < -sz || sz <= idx
|
86
|
+
|
87
|
+
@buf[__index(idx)]
|
88
|
+
end
|
89
|
+
|
90
|
+
private def slice2(i, t)
|
91
|
+
sz = size
|
92
|
+
return nil if t < 0 || i > sz
|
93
|
+
|
94
|
+
if i == sz
|
95
|
+
Deque[]
|
96
|
+
else
|
97
|
+
j = [i + t - 1, sz].min
|
98
|
+
slice_indexes(i, j)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private def slice_indexes(i, j)
|
103
|
+
i, j = j, i if reversed?
|
104
|
+
s = __index(i)
|
105
|
+
t = __index(j) + 1
|
106
|
+
Deque.new(__to_a(s, t))
|
107
|
+
end
|
108
|
+
|
109
|
+
def []=(idx, value)
|
110
|
+
@buf[__index(idx)] = value
|
111
|
+
end
|
112
|
+
|
113
|
+
def ==(other)
|
114
|
+
return false unless size == other.size
|
115
|
+
|
116
|
+
to_a == other.to_a
|
117
|
+
end
|
118
|
+
|
119
|
+
def hash
|
120
|
+
to_a.hash
|
121
|
+
end
|
122
|
+
|
123
|
+
def reverse
|
124
|
+
dup.reverse!
|
125
|
+
end
|
126
|
+
|
127
|
+
def reverse!
|
128
|
+
@reverse_count += 1
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
def reversed?
|
133
|
+
@reverse_count & 1 == 1
|
134
|
+
end
|
135
|
+
|
136
|
+
def dig(*args)
|
137
|
+
case args.size
|
138
|
+
when 0
|
139
|
+
raise ArgumentError.new("wrong number of arguments (given 0, expected 1+)")
|
140
|
+
when 1
|
141
|
+
self[args[0].to_int]
|
142
|
+
else
|
143
|
+
i = args.shift.to_int
|
144
|
+
self[i]&.dig(*args)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def each(&block)
|
149
|
+
return enum_for(:each) unless block_given?
|
150
|
+
|
151
|
+
if @head <= @tail
|
152
|
+
if reversed?
|
153
|
+
@buf[@head...@tail].reverse_each(&block)
|
154
|
+
else
|
155
|
+
@buf[@head...@tail].each(&block)
|
156
|
+
end
|
157
|
+
elsif reversed?
|
158
|
+
@buf[0...@tail].reverse_each(&block)
|
159
|
+
@buf[@head..-1].reverse_each(&block)
|
160
|
+
else
|
161
|
+
@buf[@head..-1].each(&block)
|
162
|
+
@buf[0...@tail].each(&block)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def clear
|
167
|
+
@n = 1
|
168
|
+
@buf = []
|
169
|
+
@head = 0
|
170
|
+
@tail = 0
|
171
|
+
@reverse_count = 0
|
172
|
+
self
|
173
|
+
end
|
174
|
+
|
175
|
+
def join(sep = $OFS)
|
176
|
+
to_a.join(sep)
|
177
|
+
end
|
178
|
+
|
179
|
+
def rotate!(cnt = 1)
|
180
|
+
return self if cnt == 0
|
181
|
+
|
182
|
+
cnt %= size if cnt < 0 || size > cnt
|
183
|
+
|
184
|
+
cnt.times{ push(shift) }
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
188
|
+
def rotate(cnt = 1)
|
189
|
+
return self if cnt == 0
|
190
|
+
|
191
|
+
cnt %= size if cnt < 0 || size > cnt
|
192
|
+
|
193
|
+
ret = dup
|
194
|
+
@buf = @buf.dup
|
195
|
+
cnt.times{ ret.push(ret.shift) }
|
196
|
+
ret
|
197
|
+
end
|
198
|
+
|
199
|
+
def sample
|
200
|
+
return nil if empty?
|
201
|
+
|
202
|
+
self[rand(size)]
|
203
|
+
end
|
204
|
+
|
205
|
+
def shuffle
|
206
|
+
Deque.new(to_a.shuffle)
|
207
|
+
end
|
208
|
+
|
209
|
+
def replace(other)
|
210
|
+
ary = other.to_a
|
211
|
+
@n = ary.size + 1
|
212
|
+
@buf = ary + [nil] * (@n - ary.size)
|
213
|
+
@head = 0
|
214
|
+
@tail = ary.size
|
215
|
+
@reverse_count = 0
|
216
|
+
self
|
217
|
+
end
|
218
|
+
|
219
|
+
def swap(i, j)
|
220
|
+
i = __index(i)
|
221
|
+
j = __index(j)
|
222
|
+
@buf[i], @buf[j] = @buf[j], @buf[i]
|
223
|
+
self
|
224
|
+
end
|
225
|
+
|
226
|
+
def to_a
|
227
|
+
__to_a
|
228
|
+
end
|
229
|
+
# alias to_ary to_a
|
230
|
+
|
231
|
+
private def __to_a(s = @head, t = @tail)
|
232
|
+
res = s <= t ? @buf[s...t] : @buf[s..-1].concat(@buf[0...t])
|
233
|
+
reversed? ? res.reverse : res
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_s
|
237
|
+
"#{self.class}#{to_a}"
|
238
|
+
end
|
239
|
+
|
240
|
+
def inspect
|
241
|
+
"Deque#{to_a}"
|
242
|
+
# "Deque#{to_a}(@n=#{@n}, @buf=#{@buf}, @head=#{@head}, @tail=#{@tail}, "\
|
243
|
+
# "size #{size}#{' full' if __full?}#{' rev' if reversed?})"
|
244
|
+
end
|
245
|
+
|
246
|
+
private def __push(x)
|
247
|
+
__extend if __full?
|
248
|
+
@buf[@tail] = x
|
249
|
+
@tail += 1
|
250
|
+
@tail %= @n
|
251
|
+
self
|
252
|
+
end
|
253
|
+
|
254
|
+
private def __unshift(x)
|
255
|
+
__extend if __full?
|
256
|
+
@buf[(@head - 1) % @n] = x
|
257
|
+
@head -= 1
|
258
|
+
@head %= @n
|
259
|
+
self
|
260
|
+
end
|
261
|
+
|
262
|
+
private def __pop
|
263
|
+
return nil if empty?
|
264
|
+
|
265
|
+
ret = @buf[(@tail - 1) % @n]
|
266
|
+
@tail -= 1
|
267
|
+
@tail %= @n
|
268
|
+
ret
|
269
|
+
end
|
270
|
+
|
271
|
+
private def __shift
|
272
|
+
return nil if empty?
|
273
|
+
|
274
|
+
ret = @buf[@head]
|
275
|
+
@head += 1
|
276
|
+
@head %= @n
|
277
|
+
ret
|
278
|
+
end
|
279
|
+
|
280
|
+
private def __full?
|
281
|
+
size >= @n - 1
|
282
|
+
end
|
283
|
+
|
284
|
+
private def __index(i)
|
285
|
+
l = size
|
286
|
+
raise IndexError, "index out of range: #{i}" unless -l <= i && i < l
|
287
|
+
|
288
|
+
i = -(i + 1) if reversed?
|
289
|
+
i += l if i < 0
|
290
|
+
(@head + i) % @n
|
291
|
+
end
|
292
|
+
|
293
|
+
private def __extend
|
294
|
+
if @tail + 1 == @head
|
295
|
+
tail = @buf.shift(@tail + 1)
|
296
|
+
@buf.concat(tail).concat([nil] * @n)
|
297
|
+
@head = 0
|
298
|
+
@tail = @n - 1
|
299
|
+
@n = @buf.size
|
300
|
+
else
|
301
|
+
@buf[(@tail + 1)..(@tail + 1)] = [nil] * @n
|
302
|
+
@n = @buf.size
|
303
|
+
@head += @n if @head > 0
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
data/lib/modint.rb
CHANGED
data/lib/priority_queue.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Priority Queue
|
2
|
-
# Reference: https://github.com/python/cpython/blob/
|
2
|
+
# Reference: https://github.com/python/cpython/blob/main/Lib/heapq.py
|
3
3
|
class PriorityQueue
|
4
4
|
# By default, the priority queue returns the maximum element first.
|
5
5
|
# If a block is given, the priority between the elements is determined with it.
|
@@ -13,6 +13,14 @@ class PriorityQueue
|
|
13
13
|
heapify
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.max(array)
|
17
|
+
new(array)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.min(array)
|
21
|
+
new(array){ |x, y| x < y }
|
22
|
+
end
|
23
|
+
|
16
24
|
def self.[](*array, &comp)
|
17
25
|
new(array, &comp)
|
18
26
|
end
|
@@ -46,6 +54,7 @@ class PriorityQueue
|
|
46
54
|
end
|
47
55
|
|
48
56
|
alias top get
|
57
|
+
alias first get
|
49
58
|
|
50
59
|
# Returns true if the heap is empty.
|
51
60
|
def empty?
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative "../../lib_lock/ac-library-rb/convolution"
|
2
2
|
require_relative "../../lib_lock/ac-library-rb/crt"
|
3
|
+
require_relative "../../lib_lock/ac-library-rb/deque"
|
3
4
|
require_relative "../../lib_lock/ac-library-rb/dsu"
|
4
5
|
require_relative "../../lib_lock/ac-library-rb/fenwick_tree"
|
5
6
|
require_relative "../../lib_lock/ac-library-rb/floor_sum"
|
@@ -6,6 +6,7 @@ require_relative '../lib_lock/ac-library-rb/core_ext/all.rb'
|
|
6
6
|
|
7
7
|
require_relative '../lib_lock/ac-library-rb/convolution'
|
8
8
|
require_relative '../lib_lock/ac-library-rb/crt'
|
9
|
+
require_relative '../lib_lock/ac-library-rb/dequex'
|
9
10
|
require_relative '../lib_lock/ac-library-rb/dsu'
|
10
11
|
require_relative '../lib_lock/ac-library-rb/fenwick_tree'
|
11
12
|
require_relative '../lib_lock/ac-library-rb/floor_sum'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "prime"
|
2
|
+
|
3
|
+
class Integer
|
4
|
+
# Returns the positive divisors of +self+ if +self+ is positive.
|
5
|
+
#
|
6
|
+
# == Example
|
7
|
+
# 6.divisors #=> [1, 2, 3, 6]
|
8
|
+
# 7.divisors #=> [1, 7]
|
9
|
+
# 8.divisors #=> [1, 2, 4, 8]
|
10
|
+
def divisors
|
11
|
+
if prime?
|
12
|
+
[1, self]
|
13
|
+
elsif self == 1
|
14
|
+
[1]
|
15
|
+
else
|
16
|
+
xs = prime_division.map{ |p, n| Array.new(n + 1){ |e| p**e } }
|
17
|
+
x = xs.pop
|
18
|
+
x.product(*xs).map{ |t| t.inject(:*) }.sort
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Iterates the given block for each divisor of +self+.
|
23
|
+
#
|
24
|
+
# == Example
|
25
|
+
# ds = []
|
26
|
+
# 10.divisors{ |d| ds << d }
|
27
|
+
# ds #=> [1, 2, 5, 10]
|
28
|
+
def each_divisor(&block)
|
29
|
+
block_given? ? divisors.each(&block) : enum_for(:each_divisor)
|
30
|
+
end
|
31
|
+
end
|