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
@@ -0,0 +1,308 @@
|
|
1
|
+
module AcLibraryRb
|
2
|
+
class Deque
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def self.[](*args)
|
6
|
+
new(args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(arg = [], value = nil, initial_capacity: 0)
|
10
|
+
ary = arg
|
11
|
+
ary = Array.new(arg, value) if arg.is_a?(Integer)
|
12
|
+
@n = [initial_capacity, ary.size].max + 1
|
13
|
+
@buf = ary + [nil] * (@n - ary.size)
|
14
|
+
@head = 0
|
15
|
+
@tail = ary.size
|
16
|
+
@reverse_count = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def empty?
|
20
|
+
size == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def size
|
24
|
+
(@tail - @head) % @n
|
25
|
+
end
|
26
|
+
alias length size
|
27
|
+
|
28
|
+
def <<(x)
|
29
|
+
reversed? ? __unshift(x) : __push(x)
|
30
|
+
end
|
31
|
+
|
32
|
+
def push(*args)
|
33
|
+
args.each{ |x| self << x }
|
34
|
+
self
|
35
|
+
end
|
36
|
+
alias append push
|
37
|
+
|
38
|
+
def unshift(*args)
|
39
|
+
if reversed?
|
40
|
+
args.reverse_each{ |e| __push(e) }
|
41
|
+
else
|
42
|
+
args.reverse_each{ |e| __unshift(e) }
|
43
|
+
end
|
44
|
+
self
|
45
|
+
end
|
46
|
+
alias prepend unshift
|
47
|
+
|
48
|
+
def pop
|
49
|
+
reversed? ? __shift : __pop
|
50
|
+
end
|
51
|
+
|
52
|
+
def shift
|
53
|
+
reversed? ? __pop : __shift
|
54
|
+
end
|
55
|
+
|
56
|
+
def last
|
57
|
+
self[-1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def slice(idx)
|
61
|
+
sz = size
|
62
|
+
return nil if idx < -sz || sz <= idx
|
63
|
+
|
64
|
+
@buf[__index(idx)]
|
65
|
+
end
|
66
|
+
|
67
|
+
def [](a, b = nil)
|
68
|
+
if b
|
69
|
+
slice2(a, b)
|
70
|
+
elsif a.is_a?(Range)
|
71
|
+
s = a.begin
|
72
|
+
t = a.end
|
73
|
+
t -= 1 if a.exclude_end?
|
74
|
+
slice2(s, t - s + 1)
|
75
|
+
else
|
76
|
+
slice1(a)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def at(idx)
|
81
|
+
slice1(idx)
|
82
|
+
end
|
83
|
+
|
84
|
+
private def slice1(idx)
|
85
|
+
sz = size
|
86
|
+
return nil if idx < -sz || sz <= idx
|
87
|
+
|
88
|
+
@buf[__index(idx)]
|
89
|
+
end
|
90
|
+
|
91
|
+
private def slice2(i, t)
|
92
|
+
sz = size
|
93
|
+
return nil if t < 0 || i > sz
|
94
|
+
|
95
|
+
if i == sz
|
96
|
+
Deque[]
|
97
|
+
else
|
98
|
+
j = [i + t - 1, sz].min
|
99
|
+
slice_indexes(i, j)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private def slice_indexes(i, j)
|
104
|
+
i, j = j, i if reversed?
|
105
|
+
s = __index(i)
|
106
|
+
t = __index(j) + 1
|
107
|
+
Deque.new(__to_a(s, t))
|
108
|
+
end
|
109
|
+
|
110
|
+
def []=(idx, value)
|
111
|
+
@buf[__index(idx)] = value
|
112
|
+
end
|
113
|
+
|
114
|
+
def ==(other)
|
115
|
+
return false unless size == other.size
|
116
|
+
|
117
|
+
to_a == other.to_a
|
118
|
+
end
|
119
|
+
|
120
|
+
def hash
|
121
|
+
to_a.hash
|
122
|
+
end
|
123
|
+
|
124
|
+
def reverse
|
125
|
+
dup.reverse!
|
126
|
+
end
|
127
|
+
|
128
|
+
def reverse!
|
129
|
+
@reverse_count += 1
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
def reversed?
|
134
|
+
@reverse_count & 1 == 1
|
135
|
+
end
|
136
|
+
|
137
|
+
def dig(*args)
|
138
|
+
case args.size
|
139
|
+
when 0
|
140
|
+
raise ArgumentError.new("wrong number of arguments (given 0, expected 1+)")
|
141
|
+
when 1
|
142
|
+
self[args[0].to_int]
|
143
|
+
else
|
144
|
+
i = args.shift.to_int
|
145
|
+
self[i]&.dig(*args)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def each(&block)
|
150
|
+
return enum_for(:each) unless block_given?
|
151
|
+
|
152
|
+
if @head <= @tail
|
153
|
+
if reversed?
|
154
|
+
@buf[@head...@tail].reverse_each(&block)
|
155
|
+
else
|
156
|
+
@buf[@head...@tail].each(&block)
|
157
|
+
end
|
158
|
+
elsif reversed?
|
159
|
+
@buf[0...@tail].reverse_each(&block)
|
160
|
+
@buf[@head..-1].reverse_each(&block)
|
161
|
+
else
|
162
|
+
@buf[@head..-1].each(&block)
|
163
|
+
@buf[0...@tail].each(&block)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def clear
|
168
|
+
@n = 1
|
169
|
+
@buf = []
|
170
|
+
@head = 0
|
171
|
+
@tail = 0
|
172
|
+
@reverse_count = 0
|
173
|
+
self
|
174
|
+
end
|
175
|
+
|
176
|
+
def join(sep = $OFS)
|
177
|
+
to_a.join(sep)
|
178
|
+
end
|
179
|
+
|
180
|
+
def rotate!(cnt = 1)
|
181
|
+
return self if cnt == 0
|
182
|
+
|
183
|
+
cnt %= size if cnt < 0 || size > cnt
|
184
|
+
|
185
|
+
cnt.times{ push(shift) }
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
def rotate(cnt = 1)
|
190
|
+
return self if cnt == 0
|
191
|
+
|
192
|
+
cnt %= size if cnt < 0 || size > cnt
|
193
|
+
|
194
|
+
ret = dup
|
195
|
+
@buf = @buf.dup
|
196
|
+
cnt.times{ ret.push(ret.shift) }
|
197
|
+
ret
|
198
|
+
end
|
199
|
+
|
200
|
+
def sample
|
201
|
+
return nil if empty?
|
202
|
+
|
203
|
+
self[rand(size)]
|
204
|
+
end
|
205
|
+
|
206
|
+
def shuffle
|
207
|
+
Deque.new(to_a.shuffle)
|
208
|
+
end
|
209
|
+
|
210
|
+
def replace(other)
|
211
|
+
ary = other.to_a
|
212
|
+
@n = ary.size + 1
|
213
|
+
@buf = ary + [nil] * (@n - ary.size)
|
214
|
+
@head = 0
|
215
|
+
@tail = ary.size
|
216
|
+
@reverse_count = 0
|
217
|
+
self
|
218
|
+
end
|
219
|
+
|
220
|
+
def swap(i, j)
|
221
|
+
i = __index(i)
|
222
|
+
j = __index(j)
|
223
|
+
@buf[i], @buf[j] = @buf[j], @buf[i]
|
224
|
+
self
|
225
|
+
end
|
226
|
+
|
227
|
+
def to_a
|
228
|
+
__to_a
|
229
|
+
end
|
230
|
+
# alias to_ary to_a
|
231
|
+
|
232
|
+
private def __to_a(s = @head, t = @tail)
|
233
|
+
res = s <= t ? @buf[s...t] : @buf[s..-1].concat(@buf[0...t])
|
234
|
+
reversed? ? res.reverse : res
|
235
|
+
end
|
236
|
+
|
237
|
+
def to_s
|
238
|
+
"#{self.class}#{to_a}"
|
239
|
+
end
|
240
|
+
|
241
|
+
def inspect
|
242
|
+
"Deque#{to_a}"
|
243
|
+
# "Deque#{to_a}(@n=#{@n}, @buf=#{@buf}, @head=#{@head}, @tail=#{@tail}, "\
|
244
|
+
# "size #{size}#{' full' if __full?}#{' rev' if reversed?})"
|
245
|
+
end
|
246
|
+
|
247
|
+
private def __push(x)
|
248
|
+
__extend if __full?
|
249
|
+
@buf[@tail] = x
|
250
|
+
@tail += 1
|
251
|
+
@tail %= @n
|
252
|
+
self
|
253
|
+
end
|
254
|
+
|
255
|
+
private def __unshift(x)
|
256
|
+
__extend if __full?
|
257
|
+
@buf[(@head - 1) % @n] = x
|
258
|
+
@head -= 1
|
259
|
+
@head %= @n
|
260
|
+
self
|
261
|
+
end
|
262
|
+
|
263
|
+
private def __pop
|
264
|
+
return nil if empty?
|
265
|
+
|
266
|
+
ret = @buf[(@tail - 1) % @n]
|
267
|
+
@tail -= 1
|
268
|
+
@tail %= @n
|
269
|
+
ret
|
270
|
+
end
|
271
|
+
|
272
|
+
private def __shift
|
273
|
+
return nil if empty?
|
274
|
+
|
275
|
+
ret = @buf[@head]
|
276
|
+
@head += 1
|
277
|
+
@head %= @n
|
278
|
+
ret
|
279
|
+
end
|
280
|
+
|
281
|
+
private def __full?
|
282
|
+
size >= @n - 1
|
283
|
+
end
|
284
|
+
|
285
|
+
private def __index(i)
|
286
|
+
l = size
|
287
|
+
raise IndexError, "index out of range: #{i}" unless -l <= i && i < l
|
288
|
+
|
289
|
+
i = -(i + 1) if reversed?
|
290
|
+
i += l if i < 0
|
291
|
+
(@head + i) % @n
|
292
|
+
end
|
293
|
+
|
294
|
+
private def __extend
|
295
|
+
if @tail + 1 == @head
|
296
|
+
tail = @buf.shift(@tail + 1)
|
297
|
+
@buf.concat(tail).concat([nil] * @n)
|
298
|
+
@head = 0
|
299
|
+
@tail = @n - 1
|
300
|
+
@n = @buf.size
|
301
|
+
else
|
302
|
+
@buf[(@tail + 1)..(@tail + 1)] = [nil] * @n
|
303
|
+
@n = @buf.size
|
304
|
+
@head += @n if @head > 0
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module AcLibraryRb
|
2
2
|
# Priority Queue
|
3
|
-
# Reference: https://github.com/python/cpython/blob/
|
3
|
+
# Reference: https://github.com/python/cpython/blob/main/Lib/heapq.py
|
4
4
|
class PriorityQueue
|
5
5
|
# By default, the priority queue returns the maximum element first.
|
6
6
|
# If a block is given, the priority between the elements is determined with it.
|
@@ -14,6 +14,14 @@ module AcLibraryRb
|
|
14
14
|
heapify
|
15
15
|
end
|
16
16
|
|
17
|
+
def self.max(array)
|
18
|
+
new(array)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.min(array)
|
22
|
+
new(array){ |x, y| x < y }
|
23
|
+
end
|
24
|
+
|
17
25
|
def self.[](*array, &comp)
|
18
26
|
new(array, &comp)
|
19
27
|
end
|
@@ -47,6 +55,7 @@ module AcLibraryRb
|
|
47
55
|
end
|
48
56
|
|
49
57
|
alias top get
|
58
|
+
alias first get
|
50
59
|
|
51
60
|
# Returns true if the heap is empty.
|
52
61
|
def empty?
|
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: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- universato
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prime
|
@@ -136,8 +136,10 @@ files:
|
|
136
136
|
- lib/ac-library-rb/version.rb
|
137
137
|
- lib/convolution.rb
|
138
138
|
- lib/core_ext/all.rb
|
139
|
+
- lib/core_ext/integer.rb
|
139
140
|
- lib/core_ext/modint.rb
|
140
141
|
- lib/crt.rb
|
142
|
+
- lib/deque.rb
|
141
143
|
- lib/dsu.rb
|
142
144
|
- lib/fenwick_tree.rb
|
143
145
|
- lib/floor_sum.rb
|
@@ -158,8 +160,10 @@ files:
|
|
158
160
|
- lib_helpers/ac-library-rb/all.rb
|
159
161
|
- lib_lock/ac-library-rb/convolution.rb
|
160
162
|
- lib_lock/ac-library-rb/core_ext/all.rb
|
163
|
+
- lib_lock/ac-library-rb/core_ext/integer.rb
|
161
164
|
- lib_lock/ac-library-rb/core_ext/modint.rb
|
162
165
|
- lib_lock/ac-library-rb/crt.rb
|
166
|
+
- lib_lock/ac-library-rb/deque.rb
|
163
167
|
- lib_lock/ac-library-rb/dsu.rb
|
164
168
|
- lib_lock/ac-library-rb/fenwick_tree.rb
|
165
169
|
- lib_lock/ac-library-rb/floor_sum.rb
|