ac-library-rb 0.5.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.
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
@@ -0,0 +1,130 @@
1
+ module AcLibraryRb
2
+ # induce sort (internal method)
3
+ def sa_is_induce(s, ls, sum_l, sum_s, lms)
4
+ n = s.size
5
+ sa = [-1] * n
6
+
7
+ buf = sum_s.dup
8
+ lms.each{ |lms|
9
+ if lms != n
10
+ sa[buf[s[lms]]] = lms
11
+ buf[s[lms]] += 1
12
+ end
13
+ }
14
+
15
+ buf = sum_l.dup
16
+ sa[buf[s[-1]]] = n - 1
17
+ buf[s[-1]] += 1
18
+ sa.each{ |v|
19
+ if v >= 1 && !ls[v - 1]
20
+ sa[buf[s[v - 1]]] = v - 1
21
+ buf[s[v - 1]] += 1
22
+ end
23
+ }
24
+
25
+ buf = sum_l.dup
26
+ sa.reverse_each{ |v|
27
+ if v >= 1 && ls[v - 1]
28
+ buf[s[v - 1] + 1] -= 1
29
+ sa[buf[s[v - 1] + 1]] = v - 1
30
+ end
31
+ }
32
+
33
+ return sa
34
+ end
35
+
36
+ # SA-IS (internal method)
37
+ def sa_is(s, upper)
38
+ n = s.size
39
+
40
+ return [] if n == 0
41
+ return [0] if n == 1
42
+
43
+ ls = [false] * n
44
+ (n - 2).downto(0){ |i|
45
+ ls[i] = (s[i] == s[i + 1] ? ls[i + 1] : s[i] < s[i + 1])
46
+ }
47
+
48
+ sum_l = [0] * (upper + 1)
49
+ sum_s = [0] * (upper + 1)
50
+ n.times{ |i|
51
+ if ls[i]
52
+ sum_l[s[i] + 1] += 1
53
+ else
54
+ sum_s[s[i]] += 1
55
+ end
56
+ }
57
+ 0.upto(upper){ |i|
58
+ sum_s[i] += sum_l[i]
59
+ sum_l[i + 1] += sum_s[i] if i < upper
60
+ }
61
+
62
+ lms = (1 ... n).select{ |i| !ls[i - 1] && ls[i] }
63
+ m = lms.size
64
+ lms_map = [-1] * (n + 1)
65
+ lms.each_with_index{ |lms, id| lms_map[lms] = id }
66
+
67
+ sa = sa_is_induce(s, ls, sum_l, sum_s, lms)
68
+
69
+ return sa if m == 0
70
+
71
+ sorted_lms = sa.select{ |sa| lms_map[sa] != -1 }
72
+ rec_s = [0] * m
73
+ rec_upper = 0
74
+ rec_s[lms_map[sorted_lms[0]]] = 0
75
+ 1.upto(m - 1) do |i|
76
+ l, r = sorted_lms[i - 1, 2]
77
+ end_l = lms[lms_map[l] + 1] || n
78
+ end_r = lms[lms_map[r] + 1] || n
79
+ same = true
80
+ if end_l - l != end_r - r
81
+ same = false
82
+ else
83
+ while l < end_l
84
+ break if s[l] != s[r]
85
+
86
+ l += 1
87
+ r += 1
88
+ end
89
+ same = false if l == n || s[l] != s[r]
90
+ end
91
+ rec_upper += 1 if not same
92
+ rec_s[lms_map[sorted_lms[i]]] = rec_upper
93
+ end
94
+
95
+ sa_is(rec_s, rec_upper).each_with_index{ |rec_sa, id|
96
+ sorted_lms[id] = lms[rec_sa]
97
+ }
98
+
99
+ return sa_is_induce(s, ls, sum_l, sum_s, sorted_lms)
100
+ end
101
+
102
+ # suffix array for array of integers or string
103
+ def suffix_array(s, upper = nil)
104
+ if not upper
105
+ case s
106
+ when Array
107
+ # compression
108
+ n = s.size
109
+ idx = (0 ... n).sort_by{ |i| s[i] }
110
+ t = [0] * n
111
+ upper = 0
112
+ t[idx[0]] = 0
113
+ 1.upto(n - 1){ |i|
114
+ upper += 1 if s[idx[i - 1]] != s[idx[i]]
115
+ t[idx[i]] = upper
116
+ }
117
+ s = t
118
+ when String
119
+ upper = 255
120
+ s = s.bytes
121
+ end
122
+ else
123
+ s.each{ |s|
124
+ raise ArgumentError if s < 0 || upper < s
125
+ }
126
+ end
127
+
128
+ return sa_is(s, upper)
129
+ end
130
+ end
@@ -0,0 +1,36 @@
1
+ module AcLibraryRb
2
+ require_relative './scc.rb'
3
+
4
+ # TwoSAT
5
+ # Reference: https://github.com/atcoder/ac-library/blob/master/atcoder/twosat.hpp
6
+ class TwoSAT
7
+ def initialize(n = 0)
8
+ @n = n
9
+ @answer = Array.new(n)
10
+ @scc = SCCGraph.new(2 * n)
11
+ end
12
+
13
+ attr_reader :answer
14
+
15
+ def add_clause(i, f, j, g)
16
+ raise RangeError unless (0...@n).cover?(i) && (0...@n).cover?(j)
17
+
18
+ @scc.add_edge(2 * i + (f ? 0 : 1), 2 * j + (g ? 1 : 0))
19
+ @scc.add_edge(2 * j + (g ? 0 : 1), 2 * i + (f ? 1 : 0))
20
+ nil
21
+ end
22
+
23
+ def satisfiable
24
+ id = @scc.send(:scc_ids)[1]
25
+ @n.times do |i|
26
+ return false if id[2 * i] == id[2 * i + 1]
27
+
28
+ @answer[i] = id[2 * i] < id[2 * i + 1]
29
+ end
30
+ true
31
+ end
32
+ alias satisfiable? satisfiable
33
+ end
34
+
35
+ TwoSat = TwoSAT
36
+ end
@@ -0,0 +1,34 @@
1
+ module AcLibraryRb
2
+ # this implementation is different from ACL because of calculation time
3
+ # ref : https://snuke.hatenablog.com/entry/2014/12/03/214243
4
+ # ACL implementation : https://atcoder.jp/contests/abc135/submissions/18836384 (731ms)
5
+ # this implementation : https://atcoder.jp/contests/abc135/submissions/18836378 (525ms)
6
+
7
+ def z_algorithm(s)
8
+ n = s.size
9
+ return [] if n == 0
10
+
11
+ s = s.codepoints if s.is_a?(String)
12
+
13
+ z = [0] * n
14
+ z[0] = n
15
+ i, j = 1, 0
16
+ while i < n
17
+ j += 1 while i + j < n && s[j] == s[i + j]
18
+ z[i] = j
19
+ if j == 0
20
+ i += 1
21
+ next
22
+ end
23
+ k = 1
24
+ while i + k < n && k + z[k] < j
25
+ z[i + k] = z[k]
26
+ k += 1
27
+ end
28
+ i += k
29
+ j -= k
30
+ end
31
+
32
+ return z
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ac-library-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - universato
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-05-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |-
42
+ ac-library-rb is a ruby port of AtCoder Library (ACL).
43
+ DSU(UnionFind), FenwickTree, PriorityQueue, Segtree, SCC, 2-SAT, suffix_array, lcp_array, z_algorithm, crt, inv_mod, floor_sum, max_flow, min_cost_flow......
44
+ email:
45
+ - universato@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".github/workflows/unittest.yml"
51
+ - ".gitignore"
52
+ - ".rubocop.yml"
53
+ - Gemfile
54
+ - LICENSE
55
+ - README.ja.md
56
+ - README.md
57
+ - Rakefile
58
+ - ac-library-rb.gemspec
59
+ - bin/console
60
+ - bin/lock_lib.rb
61
+ - bin/setup
62
+ - document_en/binary_index_tree.md
63
+ - document_en/convolution.md
64
+ - document_en/dsu.md
65
+ - document_en/fenwick_tree.md
66
+ - document_en/index.md
67
+ - document_en/lazy_segtree.md
68
+ - document_en/math.md
69
+ - document_en/max_flow.md
70
+ - document_en/min_cost_flow.md
71
+ - document_en/modint.md
72
+ - document_en/priority_queue.md
73
+ - document_en/segtree.md
74
+ - document_en/string.md
75
+ - document_en/two_sat.md
76
+ - document_en/union_find.md
77
+ - document_ja/convolution.md
78
+ - document_ja/dsu.md
79
+ - document_ja/fenwick_tree.md
80
+ - document_ja/index.md
81
+ - document_ja/lazy_segtree.md
82
+ - document_ja/math.md
83
+ - document_ja/max_flow.md
84
+ - document_ja/min_cost_flow.md
85
+ - document_ja/modint.md
86
+ - document_ja/priority_queue.md
87
+ - document_ja/scc.md
88
+ - document_ja/segtree.md
89
+ - document_ja/string.md
90
+ - document_ja/two_sat.md
91
+ - lib/ac-library-rb/version.rb
92
+ - lib/convolution.rb
93
+ - lib/core_ext/modint.rb
94
+ - lib/crt.rb
95
+ - lib/dsu.rb
96
+ - lib/fenwick_tree.rb
97
+ - lib/floor_sum.rb
98
+ - lib/inv_mod.rb
99
+ - lib/lazy_segtree.rb
100
+ - lib/lcp_array.rb
101
+ - lib/max_flow.rb
102
+ - lib/min_cost_flow.rb
103
+ - lib/modint.rb
104
+ - lib/pow_mod.rb
105
+ - lib/priority_queue.rb
106
+ - lib/scc.rb
107
+ - lib/segtree.rb
108
+ - lib/suffix_array.rb
109
+ - lib/two_sat.rb
110
+ - lib/z_algorithm.rb
111
+ - lib_helpers/ac-library-rb/all.rb
112
+ - lib_lock/ac-library-rb.rb
113
+ - lib_lock/ac-library-rb/convolution.rb
114
+ - lib_lock/ac-library-rb/core_ext/modint.rb
115
+ - lib_lock/ac-library-rb/crt.rb
116
+ - lib_lock/ac-library-rb/dsu.rb
117
+ - lib_lock/ac-library-rb/fenwick_tree.rb
118
+ - lib_lock/ac-library-rb/floor_sum.rb
119
+ - lib_lock/ac-library-rb/inv_mod.rb
120
+ - lib_lock/ac-library-rb/lazy_segtree.rb
121
+ - lib_lock/ac-library-rb/lcp_array.rb
122
+ - lib_lock/ac-library-rb/max_flow.rb
123
+ - lib_lock/ac-library-rb/min_cost_flow.rb
124
+ - lib_lock/ac-library-rb/modint.rb
125
+ - lib_lock/ac-library-rb/pow_mod.rb
126
+ - lib_lock/ac-library-rb/priority_queue.rb
127
+ - lib_lock/ac-library-rb/scc.rb
128
+ - lib_lock/ac-library-rb/segtree.rb
129
+ - lib_lock/ac-library-rb/suffix_array.rb
130
+ - lib_lock/ac-library-rb/two_sat.rb
131
+ - lib_lock/ac-library-rb/z_algorithm.rb
132
+ homepage: https://github.com/universato/ac-library-rb
133
+ licenses:
134
+ - CC0
135
+ metadata:
136
+ homepage_uri: https://github.com/universato/ac-library-rb
137
+ source_code_uri: https://github.com/universato/ac-library-rb
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib_lock
142
+ - lib_helpers
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: 2.3.0
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubygems_version: 3.2.11
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: ac-library-rb is a ruby port of AtCoder Library (ACL).
158
+ test_files: []