ac-library-rb 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/unittest.yml +16 -0
  3. data/.gitignore +11 -0
  4. data/.rubocop.yml +198 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +116 -0
  7. data/README.ja.md +56 -0
  8. data/README.md +41 -0
  9. data/Rakefile +11 -0
  10. data/ac-library-rb.gemspec +32 -0
  11. data/bin/console +8 -0
  12. data/bin/lock_lib.rb +27 -0
  13. data/bin/setup +8 -0
  14. data/document_en/binary_index_tree.md +3 -0
  15. data/document_en/convolution.md +67 -0
  16. data/document_en/dsu.md +132 -0
  17. data/document_en/fenwick_tree.md +99 -0
  18. data/document_en/index.md +79 -0
  19. data/document_en/lazy_segtree.md +141 -0
  20. data/document_en/math.md +104 -0
  21. data/document_en/max_flow.md +165 -0
  22. data/document_en/min_cost_flow.md +132 -0
  23. data/document_en/modint.md +263 -0
  24. data/document_en/priority_queue.md +119 -0
  25. data/document_en/segtree.md +134 -0
  26. data/document_en/string.md +106 -0
  27. data/document_en/two_sat.md +91 -0
  28. data/document_en/union_find.md +3 -0
  29. data/document_ja/convolution.md +64 -0
  30. data/document_ja/dsu.md +183 -0
  31. data/document_ja/fenwick_tree.md +83 -0
  32. data/document_ja/index.md +89 -0
  33. data/document_ja/lazy_segtree.md +135 -0
  34. data/document_ja/math.md +116 -0
  35. data/document_ja/max_flow.md +129 -0
  36. data/document_ja/min_cost_flow.md +105 -0
  37. data/document_ja/modint.md +349 -0
  38. data/document_ja/priority_queue.md +103 -0
  39. data/document_ja/scc.md +65 -0
  40. data/document_ja/segtree.md +145 -0
  41. data/document_ja/string.md +105 -0
  42. data/document_ja/two_sat.md +87 -0
  43. data/lib/ac-library-rb/version.rb +3 -0
  44. data/lib/convolution.rb +124 -0
  45. data/lib/core_ext/modint.rb +19 -0
  46. data/lib/crt.rb +52 -0
  47. data/lib/dsu.rb +44 -0
  48. data/lib/fenwick_tree.rb +48 -0
  49. data/lib/floor_sum.rb +21 -0
  50. data/lib/inv_mod.rb +26 -0
  51. data/lib/lazy_segtree.rb +149 -0
  52. data/lib/lcp_array.rb +23 -0
  53. data/lib/max_flow.rb +137 -0
  54. data/lib/min_cost_flow.rb +143 -0
  55. data/lib/modint.rb +170 -0
  56. data/lib/pow_mod.rb +13 -0
  57. data/lib/priority_queue.rb +89 -0
  58. data/lib/scc.rb +77 -0
  59. data/lib/segtree.rb +140 -0
  60. data/lib/suffix_array.rb +128 -0
  61. data/lib/two_sat.rb +34 -0
  62. data/lib/z_algorithm.rb +32 -0
  63. data/lib_helpers/ac-library-rb/all.rb +22 -0
  64. data/lib_lock/ac-library-rb.rb +22 -0
  65. data/lib_lock/ac-library-rb/convolution.rb +126 -0
  66. data/lib_lock/ac-library-rb/core_ext/modint.rb +19 -0
  67. data/lib_lock/ac-library-rb/crt.rb +54 -0
  68. data/lib_lock/ac-library-rb/dsu.rb +46 -0
  69. data/lib_lock/ac-library-rb/fenwick_tree.rb +50 -0
  70. data/lib_lock/ac-library-rb/floor_sum.rb +23 -0
  71. data/lib_lock/ac-library-rb/inv_mod.rb +28 -0
  72. data/lib_lock/ac-library-rb/lazy_segtree.rb +151 -0
  73. data/lib_lock/ac-library-rb/lcp_array.rb +25 -0
  74. data/lib_lock/ac-library-rb/max_flow.rb +139 -0
  75. data/lib_lock/ac-library-rb/min_cost_flow.rb +145 -0
  76. data/lib_lock/ac-library-rb/modint.rb +172 -0
  77. data/lib_lock/ac-library-rb/pow_mod.rb +15 -0
  78. data/lib_lock/ac-library-rb/priority_queue.rb +91 -0
  79. data/lib_lock/ac-library-rb/scc.rb +79 -0
  80. data/lib_lock/ac-library-rb/segtree.rb +142 -0
  81. data/lib_lock/ac-library-rb/suffix_array.rb +130 -0
  82. data/lib_lock/ac-library-rb/two_sat.rb +36 -0
  83. data/lib_lock/ac-library-rb/z_algorithm.rb +34 -0
  84. metadata +158 -0
data/lib/lcp_array.rb ADDED
@@ -0,0 +1,23 @@
1
+ # lcp array for array of integers or string
2
+ def lcp_array(s, sa)
3
+ s = s.bytes if s.is_a?(String)
4
+
5
+ n = s.size
6
+ rnk = [0] * n
7
+ sa.each_with_index{ |sa, id|
8
+ rnk[sa] = id
9
+ }
10
+
11
+ lcp = [0] * (n - 1)
12
+ h = 0
13
+ n.times{ |i|
14
+ h -= 1 if h > 0
15
+ next if rnk[i] == 0
16
+
17
+ j = sa[rnk[i] - 1]
18
+ h += 1 while j + h < n && i + h < n && s[j + h] == s[i + h]
19
+ lcp[rnk[i] - 1] = h
20
+ }
21
+
22
+ return lcp
23
+ end
data/lib/max_flow.rb ADDED
@@ -0,0 +1,137 @@
1
+ # MaxFlowGraph
2
+ class MaxFlow
3
+ def initialize(n = 0)
4
+ @n = n
5
+ @pos = []
6
+ @g = Array.new(n) { [] }
7
+ end
8
+
9
+ def add_edge(from, to, cap)
10
+ edge_number = @pos.size
11
+
12
+ @pos << [from, @g[from].size]
13
+
14
+ from_id = @g[from].size
15
+ to_id = @g[to].size
16
+ to_id += 1 if from == to
17
+ @g[from] << [to, to_id, cap]
18
+ @g[to] << [from, from_id, 0]
19
+
20
+ edge_number
21
+ end
22
+
23
+ def push(edge)
24
+ add_edge(*edge)
25
+ end
26
+ alias << push
27
+
28
+ # return edge = [from, to, cap, flow]
29
+ def [](i)
30
+ _e = @g[@pos[i][0]][@pos[i][1]]
31
+ _re = @g[_e[0]][_e[1]]
32
+ [@pos[i][0], _e[0], _e[-1] + _re[-1], _re[-1]]
33
+ end
34
+ alias get_edge []
35
+ alias edge []
36
+
37
+ def edges
38
+ @pos.map do |(from, id)|
39
+ _e = @g[from][id]
40
+ _re = @g[_e[0]][_e[1]]
41
+ [from, _e[0], _e[-1] + _re[-1], _re[-1]]
42
+ end
43
+ end
44
+
45
+ def change_edge(i, new_cap, new_flow)
46
+ _e = @g[@pos[i][0]][@pos[i][1]]
47
+ _re = @g[_e[0]][_e[1]]
48
+ _e[2] = new_cap - new_flow
49
+ _re[2] = new_flow
50
+ end
51
+
52
+ def flow(s, t, flow_limit = 1 << 64)
53
+ level = Array.new(@n)
54
+ iter = Array.new(@n)
55
+ que = []
56
+
57
+ flow = 0
58
+ while flow < flow_limit
59
+ bfs(s, t, level, que)
60
+ break if level[t] == -1
61
+
62
+ iter.fill(0)
63
+ while flow < flow_limit
64
+ f = dfs(t, flow_limit - flow, s, level, iter)
65
+ break if f == 0
66
+
67
+ flow += f
68
+ end
69
+ end
70
+
71
+ flow
72
+ end
73
+ alias max_flow flow
74
+
75
+ def min_cut(s)
76
+ visited = Array.new(@n, false)
77
+ que = [s]
78
+ while (q = que.shift)
79
+ visited[q] = true
80
+ @g[q].each do |(to, _rev, cap)|
81
+ if cap > 0 && !visited[to]
82
+ visited[to] = true
83
+ que << to
84
+ end
85
+ end
86
+ end
87
+ visited
88
+ end
89
+
90
+ private
91
+
92
+ def bfs(s, t, level, que)
93
+ level.fill(-1)
94
+ level[s] = 0
95
+ que.clear
96
+ que << s
97
+
98
+ while (v = que.shift)
99
+ @g[v].each do |e|
100
+ next if e[2] == 0 || level[e[0]] >= 0
101
+
102
+ level[e[0]] = level[v] + 1
103
+ return nil if e[0] == t
104
+
105
+ que << e[0]
106
+ end
107
+ end
108
+ end
109
+
110
+ def dfs(v, up, s, level, iter)
111
+ return up if v == s
112
+
113
+ res = 0
114
+ level_v = level[v]
115
+
116
+ while iter[v] < @g[v].size
117
+ i = iter[v]
118
+ e = @g[v][i]
119
+ cap = @g[e[0]][e[1]][2]
120
+ if level_v > level[e[0]] && cap > 0
121
+ d = dfs(e[0], (up - res < cap ? up - res : cap), s, level, iter)
122
+ if d > 0
123
+ @g[v][i][2] += d
124
+ @g[e[0]][e[1]][2] -= d
125
+ res += d
126
+ break if res == up
127
+ end
128
+ end
129
+ iter[v] += 1
130
+ end
131
+
132
+ res
133
+ end
134
+ end
135
+
136
+ MaxFlowGraph = MaxFlow
137
+ MFGraph = MaxFlow
@@ -0,0 +1,143 @@
1
+ require_relative './priority_queue.rb'
2
+
3
+ # Min Cost Flow Grapsh
4
+ class MinCostFlow
5
+ def initialize(n)
6
+ @n = n
7
+ @pos = []
8
+ @g_to = Array.new(n) { [] }
9
+ @g_rev = Array.new(n) { [] }
10
+ @g_cap = Array.new(n) { [] }
11
+ @g_cost = Array.new(n) { [] }
12
+ @pv = Array.new(n)
13
+ @pe = Array.new(n)
14
+ @dual = Array.new(n) { 0 }
15
+ end
16
+
17
+ def add_edge(from, to, cap, cost)
18
+ edge_number = @pos.size
19
+
20
+ @pos << [from, @g_to[from].size]
21
+
22
+ from_id = @g_to[from].size
23
+ to_id = @g_to[to].size
24
+ to_id += 1 if from == to
25
+
26
+ @g_to[from] << to
27
+ @g_rev[from] << to_id
28
+ @g_cap[from] << cap
29
+ @g_cost[from] << cost
30
+
31
+ @g_to[to] << from
32
+ @g_rev[to] << from_id
33
+ @g_cap[to] << 0
34
+ @g_cost[to] << -cost
35
+
36
+ edge_number
37
+ end
38
+
39
+ def get_edge(i)
40
+ from, id = @pos[i]
41
+ to = @g_to[from][id]
42
+ rid = @g_rev[from][id]
43
+ [from, to, @g_cap[from][id] + @g_cap[to][rid], @g_cap[to][rid], @g_cost[from][id]]
44
+ end
45
+ alias edge get_edge
46
+ alias [] get_edge
47
+
48
+ def edges
49
+ @pos.map do |(from, id)|
50
+ to = @g_to[from][id]
51
+ rid = @g_rev[from][id]
52
+ [from, to, @g_cap[from][id] + @g_cap[to][rid], @g_cap[to][rid], @g_cost[from][id]]
53
+ end
54
+ end
55
+
56
+ def flow(s, t, flow_limit = Float::MAX)
57
+ slope(s, t, flow_limit).last
58
+ end
59
+ alias min_cost_max_flow flow
60
+
61
+ def dual_ref(s, t)
62
+ dist = Array.new(@n, Float::MAX)
63
+ @pv.fill(-1)
64
+ @pe.fill(-1)
65
+ vis = Array.new(@n, false)
66
+
67
+ que = PriorityQueue.new { |par, chi| par[0] < chi[0] }
68
+ dist[s] = 0
69
+ que.push([0, s])
70
+
71
+ while (v = que.pop)
72
+ v = v[1]
73
+
74
+ next if vis[v]
75
+
76
+ vis[v] = true
77
+ break if v == t
78
+
79
+ @g_to[v].size.times do |i|
80
+ to = @g_to[v][i]
81
+ next if vis[to] || @g_cap[v][i] == 0
82
+
83
+ cost = @g_cost[v][i] - @dual[to] + @dual[v]
84
+ next unless dist[to] - dist[v] > cost
85
+
86
+ dist[to] = dist[v] + cost
87
+ @pv[to] = v
88
+ @pe[to] = i
89
+ que.push([dist[to], to])
90
+ end
91
+ end
92
+
93
+ return false unless vis[t]
94
+
95
+ @n.times do |i|
96
+ next unless vis[i]
97
+
98
+ @dual[i] -= dist[t] - dist[i]
99
+ end
100
+
101
+ true
102
+ end
103
+
104
+ def slope(s, t, flow_limit = Float::MAX)
105
+ flow = 0
106
+ cost = 0
107
+ prev_cost = -1
108
+ result = [[flow, cost]]
109
+
110
+ while flow < flow_limit
111
+ break unless dual_ref(s, t)
112
+
113
+ c = flow_limit - flow
114
+ v = t
115
+ while v != s
116
+ c = @g_cap[@pv[v]][@pe[v]] if c > @g_cap[@pv[v]][@pe[v]]
117
+ v = @pv[v]
118
+ end
119
+
120
+ v = t
121
+ while v != s
122
+ nv = @pv[v]
123
+ id = @pe[v]
124
+ @g_cap[nv][id] -= c
125
+ @g_cap[v][@g_rev[nv][id]] += c
126
+ v = nv
127
+ end
128
+
129
+ d = -@dual[s]
130
+ flow += c
131
+ cost += c * d
132
+ result.pop if prev_cost == d
133
+ result << [flow, cost]
134
+ prev_cost = d
135
+ end
136
+
137
+ result
138
+ end
139
+ alias min_cost_slop slope
140
+ end
141
+
142
+ MCF = MinCostFlow
143
+ MCFGraph = MinCostFlow
data/lib/modint.rb ADDED
@@ -0,0 +1,170 @@
1
+ require_relative './core_ext/modint.rb'
2
+
3
+ # ModInt
4
+ class ModInt < Numeric
5
+ class << self
6
+ def set_mod(mod)
7
+ raise ArgumentError unless mod.is_a? Integer and 1 <= mod
8
+
9
+ $_mod = mod
10
+ $_mod_is_prime = ModInt.prime?(mod)
11
+ end
12
+
13
+ def mod=(mod)
14
+ set_mod mod
15
+ end
16
+
17
+ def mod
18
+ $_mod
19
+ end
20
+
21
+ def raw(val)
22
+ x = allocate
23
+ x.val = val.to_i
24
+ x
25
+ end
26
+
27
+ def prime?(n)
28
+ return false if n <= 1
29
+ return true if n == 2 or n == 7 or n == 61
30
+ return false if (n & 1) == 0
31
+
32
+ d = n - 1
33
+ d >>= 1 while (d & 1) == 0
34
+ [2, 7, 61].each do |a|
35
+ t = d
36
+ y = a.pow(t, n)
37
+ while t != n - 1 and y != 1 and y != n - 1
38
+ y = y * y % n
39
+ t <<= 1
40
+ end
41
+ return false if y != n - 1 and (t & 1) == 0
42
+ end
43
+ true
44
+ end
45
+
46
+ def inv_gcd(a, b)
47
+ a %= b
48
+ return [b, 0] if a == 0
49
+
50
+ s, t = b, a
51
+ m0, m1 = 0, 1
52
+ while t != 0
53
+ u = s / t
54
+ s -= t * u
55
+ m0 -= m1 * u
56
+ s, t = t, s
57
+ m0, m1 = m1, m0
58
+ end
59
+ m0 += b / s if m0 < 0
60
+ [s, m0]
61
+ end
62
+ end
63
+
64
+ attr_accessor :val
65
+
66
+ alias to_i val
67
+
68
+ def initialize(val = 0)
69
+ @val = val.to_i % $_mod
70
+ end
71
+
72
+ def inc!
73
+ @val += 1
74
+ @val = 0 if @val == $_mod
75
+ self
76
+ end
77
+
78
+ def dec!
79
+ @val = $_mod if @val == 0
80
+ @val -= 1
81
+ self
82
+ end
83
+
84
+ def add!(other)
85
+ @val = (@val + other.to_i) % $_mod
86
+ self
87
+ end
88
+
89
+ def sub!(other)
90
+ @val = (@val - other.to_i) % $_mod
91
+ self
92
+ end
93
+
94
+ def mul!(other)
95
+ @val = @val * other.to_i % $_mod
96
+ self
97
+ end
98
+
99
+ def div!(other)
100
+ mul! inv_internal(other.to_i)
101
+ end
102
+
103
+ def +@
104
+ self
105
+ end
106
+
107
+ def -@
108
+ ModInt.raw($_mod - @val)
109
+ end
110
+
111
+ def **(other)
112
+ $_mod == 1 ? 0 : ModInt.raw(@val.pow(other, $_mod))
113
+ end
114
+ alias pow **
115
+
116
+ def inv
117
+ ModInt.raw(inv_internal(@val) % $_mod)
118
+ end
119
+
120
+ def coerce(other)
121
+ [ModInt(other), self]
122
+ end
123
+
124
+ def +(other)
125
+ dup.add! other
126
+ end
127
+
128
+ def -(other)
129
+ dup.sub! other
130
+ end
131
+
132
+ def *(other)
133
+ dup.mul! other
134
+ end
135
+
136
+ def /(other)
137
+ dup.div! other
138
+ end
139
+
140
+ def ==(other)
141
+ @val == other.to_i
142
+ end
143
+
144
+ def dup
145
+ ModInt.raw(@val)
146
+ end
147
+
148
+ def to_int
149
+ @val
150
+ end
151
+
152
+ def to_s
153
+ @val.to_s
154
+ end
155
+
156
+ def inspect
157
+ "#{@val} mod #{$_mod}"
158
+ end
159
+
160
+ private
161
+
162
+ def inv_internal(a)
163
+ if $_mod_is_prime
164
+ a != 0 ? a.pow($_mod - 2, $_mod) : raise(RangeError, 'no inverse')
165
+ else
166
+ g, x = ModInt.inv_gcd(a, $_mod)
167
+ g == 1 ? x : raise(RangeError, 'no inverse')
168
+ end
169
+ end
170
+ end