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
@@ -0,0 +1,106 @@
1
+ # String
2
+
3
+ The substring of the `a`-th to `b-1`-th element of the string `s` is written as `s[a..b)`.
4
+
5
+
6
+ ## suffix_array
7
+
8
+ ```ruby
9
+ (1) suffix_array(s)
10
+ (2) suffix_array(a)
11
+ (3) suffix_array(a, upper)
12
+ ```
13
+ For a string `s` of length `n`, returns an array of `Integer` of length `n` as a Suffix Array.
14
+
15
+ Suffix Array `sa` is a permutation of `0 ... ... n`, and for each `i`, it is a permutation of `s[sa[i]. .n) < s[sa[i+1]. .n)` is satisfied.
16
+
17
+ This concept of Suffix Array can also be applied to general columns and works for `a`, an array of elements comparable with `<=>` operator. 1.
18
+
19
+ ### 1. `suffix_array(s)`
20
+
21
+ Convert internally to a sequence of bytes by `s.bytes`.
22
+
23
+ **Constraints**
24
+
25
+ - `s` is a string consisting only of characters with character code 255 or less.
26
+
27
+ **Complexity**
28
+
29
+ - `O(|s|)`
30
+
31
+ ### 2. `suffix_array(a)`
32
+
33
+ Inside, so-called coordinate compression is performed. Elements are converted to non-negative integers keeping their size relation.
34
+
35
+ **Constraints**
36
+
37
+ - The elements of `a` are comparable to each other with the `<=>` operator.
38
+
39
+ **Complexity**
40
+
41
+ - Assuming elements can be compared in constant time, `O(|a| log |a|)`
42
+
43
+ ### 3. `suffix_array(a, upper)`
44
+
45
+ **Constraints**
46
+
47
+ - `a` is an array of `Integer`.
48
+
49
+ - For all elements `x` of `a`, `0 ≤ x ≤ upper`.
50
+
51
+ **Complexity**
52
+
53
+ - `O(|a| + upper)`
54
+
55
+ ## lcp_array
56
+
57
+ ```ruby
58
+ lcp_array(s, sa)
59
+ ```
60
+
61
+ It returns an array of `Integer` of length `n-1` as an LCP Array of length `n` for strings `s`. The `i` th element is the length of LCP ( Longest Common Prefix ) for `s[sa[i]. .n)` and `s[sa[i+1]. .n)`.
62
+
63
+ This also works for general columns as well as `suffix_array`.
64
+
65
+ **Constraints**
66
+
67
+ - `sa` is a Suffix Array of `s`.
68
+
69
+ - If `s` is a string, `s` consists only of characters with character code 255 or less.
70
+
71
+ **Complexity**
72
+
73
+ - `O(|s|)`
74
+
75
+ ## z_algorithm
76
+
77
+ ```ruby
78
+ z_algorithm(s)
79
+ ```
80
+
81
+ It returns an array of `Integer` of length `n`, where `n` is the length of the input array. The `i` th element is the length of LCP ( Longest Common Prefix ) of `s[0..n)` and `s[i..n)`.
82
+
83
+ **Constraints**
84
+
85
+ - The elements of `s` can be compared with each other with the `==` operator
86
+
87
+
88
+ **Complexity**
89
+
90
+ - `O(|s|)`
91
+
92
+ <hr>
93
+
94
+ ## Verified
95
+
96
+ - suffix_array, lcp_array
97
+ - [I - Number of Substrings](https://atcoder.jp/contests/practice2/tasks/practice2_i)
98
+ - [AC 1362 ms](https://atcoder.jp/contests/practice2/submissions/17194669)
99
+ - z_algorithm
100
+ - [ABC135 F - Strings of Eternity](https://atcoder.jp/contests/abc135/tasks/abc135_f)
101
+ - [AC 1076 ms](https://atcoder.jp/contests/abc135/submissions/16656965)
102
+
103
+ ## Links
104
+
105
+ - AtCoder Library
106
+ - [Document String(HTML)](https://atcoder.github.io/ac-library/master/document_ja/string.html)
@@ -0,0 +1,91 @@
1
+ # 2-SAT
2
+
3
+ It solves 2-SAT.
4
+
5
+ For variables x_0, x_1, ..., x_N-1 and clauses with form
6
+
7
+ (x_i = f) ∨ (x_j = g)
8
+
9
+ it decides whether there is a truth assignment that satisfies all clauses.
10
+
11
+
12
+ **Alias**
13
+
14
+ `TwoSAT`, `TwoSat`
15
+
16
+ <hr>
17
+
18
+ ## Class Methods
19
+
20
+ ### new(n = 0) -> TwoSAT
21
+
22
+ ```ruby
23
+ ts = TwoSAT.new(n)
24
+ ```
25
+
26
+ It creates a 2-SAT of `n` variables and `0` clauses.
27
+
28
+ **Complexity**
29
+
30
+ O(n)
31
+
32
+ <hr>
33
+
34
+ ## Instance Methods
35
+
36
+ ### add_clause(i, f, j, g) -> nil
37
+
38
+ `i: Integer`, `f: bool`, `j: Integer`, `g: bool`
39
+
40
+ ```ruby
41
+ ts.add_clause(i, true, j, false)
42
+ ```
43
+
44
+ It adds a clause (x_i = f) ∨ (x_j = g).
45
+
46
+ **Constraints**
47
+
48
+ - `0 <= i < n`
49
+ - `0 <= j < n`
50
+
51
+ **Complexity**
52
+
53
+ - `O(1)` amortized
54
+
55
+ ### satisfiable? -> bool
56
+
57
+ ```ruby
58
+ ts.satisfiable?
59
+ ```
60
+
61
+ If there is a truth assignment that satisfies all clauses, it returns `true`. Otherwise, it returns `false`.
62
+
63
+ **Alias**
64
+
65
+ `satisfiable?`, `satisfiable`
66
+
67
+ **Complexity**
68
+
69
+ `O(n + m)`, where `m` is the number of added clauses.
70
+
71
+ ### answer -> Array(bool)
72
+
73
+ ```ruby
74
+ ts.answer
75
+ ```
76
+
77
+ It returns a truth assignment that `satisfie` all clauses of the last call of satisfiable. If we call it before calling `satisfiable` or when the last call of `satisfiable` returns `false`, it returns the vector of length `n` with undefined elements.
78
+
79
+ **Complexity**
80
+
81
+ - `O(n)`
82
+
83
+ ## Verified
84
+
85
+ - [H - Two SAT](https://atcoder.jp/contests/practice2/tasks/practice2_h)
86
+ - [163 ms](https://atcoder.jp/contests/practice2/submissions/16655036 )
87
+
88
+ ## Links
89
+
90
+ - AtCoder Library(ACL)
91
+ - [Documetn twosat.html](https://atcoder.github.io/ac-library/master/document_ja/twosat.html)
@@ -0,0 +1,3 @@
1
+ See [DSU document (dsu.md)](https://github.com/universato/ac-library-rb/blob/main/document_en/dsu.md).
2
+
3
+ DSU is an alias of UnionFind.
@@ -0,0 +1,64 @@
1
+ # Convolution
2
+
3
+ 畳み込みを行います。長さ`N`の`Integer`の配列`a[0],a[1],...,a[N-1]`と長さ`M`の`Integer`の配列`b[0],b[1],...,b[M-1]`から畳み込みを計算し、長さ`N+M-1`の`Integer`の配列`c`として返します。
4
+
5
+ ## convolution
6
+
7
+ ```ruby
8
+ (1) conv = Convolution.new(m = 998244353)
9
+ (2) conv = Convolution.new(m, primitive_root)
10
+ ```
11
+
12
+ 畳み込みを`mod m`で計算するためのオブジェクトを作成します。
13
+
14
+ `primitive_root`は法`m`に対する原始根である必要があります。与えられなかった場合は、内部で最小の原始根を計算します。
15
+
16
+ **制約**
17
+
18
+ - `2≦m`
19
+
20
+ - `m`は素数
21
+
22
+ - ((2)のみ) `primitive_root`は法`m`に対する原始根
23
+
24
+ **計算量**
25
+
26
+ 1. `O(sqrt m)`
27
+
28
+ 2. `O(log m)`
29
+
30
+ ### 使用方法
31
+
32
+ 実際の計算は、上で作成したオブジェクト`conv`を用いて次のように行います。
33
+
34
+ ```ruby
35
+ c = conv.convolution(a, b)
36
+ ```
37
+
38
+ `a`と`b`の少なくとも一方が空配列の場合は空配列を返します。
39
+
40
+ **制約**
41
+
42
+ - `2^c|(m-1)`かつ`|a|+|b|-1<=2^c`なる`c`が存在する
43
+
44
+ **計算量**
45
+
46
+ - `O((|a|+|b|) log (|a|+|b|))`
47
+
48
+ ## convolution_ll
49
+
50
+ `convolution`の`m`として十分大きな素数を用いることで対応できます。
51
+
52
+ `1e15`を超える`NTT-Friendly`な素数の1例として、`1125900443713537 = 2^29×2097153+1`があります。
53
+
54
+ # Verified
55
+
56
+ - [C - 高速フーリエ変換](https://atcoder.jp/contests/atc001/tasks/fft_c)
57
+ - `m = 1012924417`
58
+ [1272ms](https://atcoder.jp/contests/atc001/submissions/17193829)
59
+ - `m = 1125900443713537`
60
+ [2448 ms](https://atcoder.jp/contests/atc001/submissions/17193739)
61
+
62
+ # 参考
63
+
64
+ - [本家 ACL のドキュメント Convolution](https://atcoder.github.io/ac-library/master/document_ja/convolution.html)
@@ -0,0 +1,183 @@
1
+ # DSU - Disjoint Set Union
2
+
3
+ 別名: Union Find (むしろ、こちらが有名)
4
+
5
+ 無向グラフに対して、
6
+
7
+ - 辺の追加(2頂点の連結)
8
+ - 2頂点が連結かの判定(別の頂点を通して行き来できることを含みます)
9
+
10
+ をならし`O(α(n))`時間で高速に計算できます。
11
+
12
+
13
+ また、内部的に、各連結成分ごとに代表元(代表となる頂点)を1つ持っています。
14
+
15
+ 辺の追加により連結成分がマージされるとき、元の連結成分の代表元のどちらかが新たな代表元になります。
16
+
17
+ ## 使い方
18
+
19
+ ```rb
20
+ d = DSU.new(5)
21
+ p d.groups # => [[0], [1], [2], [3], [4]]
22
+ p d.same?(2, 3) # => false
23
+ p d.size(2) # => 1
24
+
25
+ d.merge(2, 3)
26
+ p d.groups # => [[0], [1], [2, 3], [4]]
27
+ p d.same?(2, 3) # => true
28
+ p d.size(2) # => 2
29
+ ```
30
+
31
+ ## 特異メソッド
32
+
33
+ ### new(n = 0) -> DSU
34
+
35
+ ```rb
36
+ d = DSU.new(n)
37
+ ```
38
+
39
+ `n` 頂点, `0` 辺の無向グラフを生成します。
40
+
41
+ 頂点の番号は `0` 始まりで数え、`n - 1` までになります。
42
+
43
+ **計算量**
44
+
45
+ - `O(n)`
46
+
47
+
48
+ **エイリアス**
49
+
50
+ - `DSU`
51
+ - `DisjointSetUnion`
52
+ - `UnionFind`
53
+ - `UnionFindTree`
54
+
55
+ ## インスタンスメソッド
56
+
57
+ ### merge(a, b) -> Integer
58
+
59
+ ```rb
60
+ d.merge(a, b)
61
+ ```
62
+
63
+ 頂点 `a` と頂点 `b`を連結させます。
64
+ `a`, `b` が既に連結だった場合はその代表元、非連結だった場合は連結させたあとの新たな代表元を返します。
65
+
66
+ 計算量 ならしO(α(n))
67
+
68
+ **エイリアス**
69
+
70
+ - `merge`
71
+ - `unite`
72
+
73
+ ### same?(a, b) -> bool
74
+
75
+ ```rb
76
+ d.same?(a, b)
77
+ ```
78
+
79
+ 頂点aと頂点bが連結であるとき `true` を返し、そうでないときは `false` を返します。
80
+
81
+ **計算量**
82
+
83
+ - ならし `O(α(n))`
84
+
85
+ **エイリアス**
86
+
87
+ - `same?`
88
+ - `same`
89
+
90
+ ### leader(a) -> Integer
91
+
92
+ ```rb
93
+ d.leader(a)
94
+ ```
95
+
96
+ 頂点 `a` の属する連結成分の代表(根)の頂点を返します。
97
+
98
+ **計算量**
99
+
100
+ - ならし `O(α(n))`
101
+
102
+ **エイリアス**
103
+
104
+ - `leader`
105
+ - `root`
106
+ - `find`
107
+
108
+ ### size(a) -> Integer
109
+
110
+ ```rb
111
+ d.size(3)
112
+ ```
113
+
114
+ 頂点 `a` の属する連結成分の頂点数(サイズ)を返します。
115
+
116
+ **計算量**
117
+
118
+ - ならし `O(α(n))`
119
+
120
+ ### groups -> [[Integer]]
121
+
122
+ ```rb
123
+ d.groups
124
+ ```
125
+
126
+ グラフを連結成分に分けて、その情報を返します。
127
+
128
+ 返り値は2次元配列で、内側・外側ともに配列内の順番は未定義です。
129
+
130
+ **計算量**
131
+
132
+ - `O(n)`
133
+
134
+ ## Verified
135
+
136
+ - [A \- Disjoint Set Union](https://atcoder.jp/contests/practice2/tasks/practice2_a)
137
+
138
+ ## 参考リンク
139
+
140
+ - 当ライブラリ
141
+ - [当ライブラリの実装コード dsu.rb](https://github.com/universato/ac-library-rb/blob/master/lib/dsu.rb)
142
+ - [当ライブラリのテストコード dsu_test.rb](https://github.com/universato/ac-library-rb/blob/master/test/dsu_test.rb)
143
+ - 本家ライブラリ
144
+ - [本家ACLのドキュメント dsu.md](https://github.com/atcoder/ac-library/blob/master/document_ja/dsu.md)
145
+ - [本家ACLのコード dsu.hpp](https://github.com/atcoder/ac-library/blob/master/atcoder/dsu.hpp)
146
+
147
+ ## その他
148
+
149
+ ### DSUよりUnionFindの名称の方が一般的では?
150
+
151
+ UnionFindの方が一般的だと思いますが、本家ライブラリに合わせています。なお、`UnionFind`をクラスのエイリアスとしています。
152
+
153
+ https://twitter.com/3SAT_IS_IN_P/status/1310122929284210689 (2020/9/27)
154
+
155
+ Google Scholar によると
156
+ - "union find": 8,550件
157
+ - "union find data structure": 1,970件
158
+ - "disjoint set union": 1,610 件
159
+ - "disjoint set data structure": 1,030 件
160
+
161
+ ### メソッドのエイリアスについて
162
+
163
+ 本家ライブラリでは`same`ですが、真偽値を返すメソッドなのでRubyらしく`same?`をエイリアスとして持ちます。`same`はdeprecated(非推奨)ですので、`same?`を使って下さい。
164
+
165
+ 本家は`merge`ですが、`unite`もエイリアスに持ちます。`unite`は`UnionFind`に合っているし、蟻本などでも一般的にもよく使われています。
166
+
167
+ 本家は`leader`ですが、`UnionFind`に合っていて一般的であろう`find`や`root`もエイリアスとして持ちます。
168
+
169
+ ### mergeの返り値について
170
+
171
+ 本家ライブラリの実装に合わせて、`merge`メソッドは新たにマージしたか否かにかかわらず、代表元を返しています。
172
+
173
+ ただ、新たに結合した場合には代表元を返して、そうでない場合は`nil`か`false`を返すような`merge?`(あるいは`merge!`)を入れようという案があります。Rubyに, true/false以外を返す` nonzero?`などもあるので、`merge?`という名称は良いと思います。
174
+
175
+ ### 実装の説明
176
+
177
+ 本家ライブラリに合わせて、内部のデータを`@parent_or_size`というインスタンス変数名で持っています。これは、根(代表元)となる要素の場合は、その連結成分の要素数(サイズ)に-1を乗じた値を返し、それ以外の要素の場合に、その要素の属する連結成分の代表(根)の番号を返します。
178
+
179
+ なお、インスタンスが初期化され、まだどの頂点どうしも連結されていないときは、全ての頂点が自分自身を代表元とし、サイズ1の連結成分が頂点の数だけできます。そのため、初期化されたときは、内部の配列`@parent_or_size`は、要素が全て-1となります。
180
+
181
+ ### 変更履歴
182
+
183
+ 2020/10/25 [PR #64] メソッド`groups`(正確には内部で定義されている`groups_with_leader`)のバグを修正しました。