ac-library-rb 0.7.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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}(@n=#{@n}, @buf=#{@buf}, @head=#{@head}, @tail=#{@tail}, size #{size}#{if __full?
243
+ ' full'
244
+ end}#{' 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
@@ -142,6 +142,18 @@ module AcLibraryRb
142
142
  @val == other.to_i
143
143
  end
144
144
 
145
+ def pred
146
+ dup.add!(-1)
147
+ end
148
+
149
+ def succ
150
+ dup.add! 1
151
+ end
152
+
153
+ def zero?
154
+ @val == 0
155
+ end
156
+
145
157
  def dup
146
158
  ModInt.raw(@val)
147
159
  end
@@ -1,6 +1,6 @@
1
1
  module AcLibraryRb
2
2
  # Priority Queue
3
- # Reference: https://github.com/python/cpython/blob/master/Lib/heapq.py
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?
@@ -4,7 +4,7 @@ module AcLibraryRb
4
4
  # initialize graph with n vertices
5
5
  def initialize(n)
6
6
  @n = n
7
- @edges = []
7
+ @edges = Array.new(n) { [] }
8
8
  end
9
9
 
10
10
  # add directed edge
@@ -14,7 +14,7 @@ module AcLibraryRb
14
14
  raise ArgumentError.new(msg)
15
15
  end
16
16
 
17
- @edges << [from, to]
17
+ @edges[from] << to
18
18
  self
19
19
  end
20
20
 
@@ -29,7 +29,7 @@ module AcLibraryRb
29
29
 
30
30
  # returns list of strongly connected components
31
31
  # the components are sorted in topological order
32
- # O(@n + @edges.size)
32
+ # O(@n + @edges.sum(&:size))
33
33
  def scc
34
34
  group_num, ids = scc_ids
35
35
  groups = Array.new(group_num) { [] }
@@ -40,48 +40,50 @@ module AcLibraryRb
40
40
  private
41
41
 
42
42
  def scc_ids
43
- start, elist = csr
44
- now_ord = group_num = 0
45
- visited, low, ord, ids = [], [], [-1] * @n, []
46
- dfs = ->(v) {
47
- low[v] = ord[v] = now_ord
48
- now_ord += 1
49
- visited << v
50
- (start[v]...start[v + 1]).each do |i|
51
- to = elist[i]
52
- low[v] = if ord[to] == -1
53
- dfs.(to)
54
- [low[v], low[to]].min
55
- else
56
- [low[v], ord[to]].min
57
- end
58
- end
59
- if low[v] == ord[v]
60
- loop do
61
- u = visited.pop
62
- ord[u] = @n
63
- ids[u] = group_num
43
+ now_ord = 0
44
+
45
+ visited = []
46
+ low = Array.new(@n, 1 << 60)
47
+ ord = Array.new(@n, -1)
48
+ group_num = 0
49
+
50
+ (0...@n).each do |v|
51
+ next if ord[v] != -1
52
+
53
+ stack = [[v, 0]]
54
+
55
+ while (v, i = stack.pop)
56
+ if i == 0
57
+ visited << v
58
+ low[v] = ord[v] = now_ord
59
+ now_ord += 1
60
+ end
61
+
62
+ while i < @edges[v].size
63
+ u = @edges[v][i]
64
+ i += 1
65
+
66
+ if ord[u] == -1
67
+ stack << [v, i] << [u, 0]
68
+ break 1
69
+ end
70
+ end and next
71
+
72
+ low[v] = [low[v], @edges[v].map { |e| low[e] }.min || @n].min
73
+ next if low[v] != ord[v]
74
+
75
+ while (u = visited.pop)
76
+ low[u] = @n
77
+ ord[u] = group_num
64
78
  break if u == v
65
79
  end
66
80
  group_num += 1
67
- end
68
- }
69
- @n.times { |i| dfs.(i) if ord[i] == -1 }
70
- ids = ids.map { |x| group_num - 1 - x }
71
- [group_num, ids]
72
- end
73
81
 
74
- def csr
75
- start = [0] * (@n + 1)
76
- elist = [nil] * @edges.size
77
- @edges.each { |(i, _)| start[i + 1] += 1 }
78
- @n.times { |i| start[i + 1] += start[i] }
79
- counter = start.dup
80
- @edges.each do |(i, j)|
81
- elist[counter[i]] = j
82
- counter[i] += 1
82
+ end
83
83
  end
84
- [start, elist]
84
+
85
+ ord.map! { |e| group_num - e - 1 }
86
+ [group_num, ord]
85
87
  end
86
88
  end
87
89
  end
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.7.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - universato
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-26 00:00:00.000000000 Z
11
+ date: 2023-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prime
@@ -138,6 +138,7 @@ files:
138
138
  - lib/core_ext/all.rb
139
139
  - lib/core_ext/modint.rb
140
140
  - lib/crt.rb
141
+ - lib/deque.rb
141
142
  - lib/dsu.rb
142
143
  - lib/fenwick_tree.rb
143
144
  - lib/floor_sum.rb
@@ -160,6 +161,7 @@ files:
160
161
  - lib_lock/ac-library-rb/core_ext/all.rb
161
162
  - lib_lock/ac-library-rb/core_ext/modint.rb
162
163
  - lib_lock/ac-library-rb/crt.rb
164
+ - lib_lock/ac-library-rb/deque.rb
163
165
  - lib_lock/ac-library-rb/dsu.rb
164
166
  - lib_lock/ac-library-rb/fenwick_tree.rb
165
167
  - lib_lock/ac-library-rb/floor_sum.rb