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,103 @@
1
+ # PriorityQueue
2
+
3
+ 優先度付きキューです。
4
+ デフォルトでは降順で要素を保持します。
5
+
6
+ **エイリアス** `HeapQueue`
7
+
8
+ ## 特異メソッド
9
+
10
+ ### new(array = []) -> PriorityQueue
11
+
12
+ ```ruby
13
+ PriorityQueue.new
14
+ pq = PriorityQueue.new([1, -1, 100])
15
+ pq.pop # => 100
16
+ pq.pop # => 1
17
+ pq.pop # => -1
18
+ ```
19
+
20
+ 引数に与えた配列から優先度付きキューを構築します。
21
+
22
+ **計算量** `O(n)` (`n` は配列の要素数)
23
+
24
+ ### new(array = []) {|x, y| ... } -> PriorityQueue
25
+
26
+ ```ruby
27
+ PriorityQueue.new([1, -1, 100]) {|x, y| x < y }
28
+ pq.pop # => -1
29
+ pq.pop # => 1
30
+ pq.pop # => 100
31
+ ```
32
+
33
+ 引数に与えた配列から優先度付きキューを構築します。
34
+ ブロックで比較関数を渡すことができます。比較関数が渡されると、それを使って要素の優先度が計算されます。
35
+
36
+ 比較関数で比較できるなら、任意のオブジェクトをキューの要素にできます。
37
+
38
+ **計算量** `O(n)` (`n` は配列の要素数)
39
+
40
+ ## インスタンスメソッド
41
+
42
+ ### push(item)
43
+
44
+ ```ruby
45
+ pq.push(10)
46
+ ```
47
+
48
+ 要素を追加します。
49
+
50
+ **エイリアス** `<<`, `append`
51
+
52
+ **計算量** `O(log n)` (`n` はキューの要素数)
53
+
54
+ ### pop -> 最も優先度の高い要素 | nil
55
+
56
+ ```ruby
57
+ pq.pop # => 100
58
+ ```
59
+
60
+ 最も優先度の高い要素をキューから取り除き、それを返します。キューが空のときは `nil` を返します。
61
+
62
+ **計算量** `O(log n)` (`n` はキューの要素数)
63
+
64
+ ### get -> 最も優先度の高い要素 | nil
65
+
66
+ ```ruby
67
+ pq.get # => 10
68
+ ```
69
+
70
+ 最も優先度の高い要素を**取り除くことなく**、その値を返します。
71
+
72
+ キューが空のときは `nil` を返します。
73
+
74
+ **エイリアス** `top`
75
+
76
+ **計算量** `O(1)`
77
+
78
+ ### empty? -> bool
79
+
80
+ ```ruby
81
+ pq.empty? # => false
82
+ ```
83
+
84
+ キューの中身が空なら `true`、そうでないなら `false` を返します。
85
+
86
+ **計算量** `O(1)`
87
+
88
+ ### heap -> Array(キューの要素)
89
+
90
+ ```ruby
91
+ pq.heap
92
+ ```
93
+
94
+ キューが内部で持っている二分ヒープを返します。
95
+
96
+ ## Verified
97
+
98
+ - [Aizu Online Judge ALDS1_9_C Priority Queue](https://onlinejudge.u-aizu.ac.jp/problems/ALDS1_9_C)
99
+ - [code](https://onlinejudge.u-aizu.ac.jp/solutions/problem/ALDS1_9_C/review/4835681/qsako6/Ruby)
100
+
101
+ ## 参考
102
+
103
+ - [cpython/heapq.py at master - python/cpython](https://github.com/python/cpython/blob/master/Lib/heapq.py)
@@ -0,0 +1,65 @@
1
+ # SCC
2
+
3
+ Strongly Connected Components
4
+
5
+ 有向グラフを強連結成分分解します。
6
+
7
+ ## 特異メソッド
8
+
9
+ ### new(n = 0) -> SCC
10
+
11
+ ```ruby
12
+ graph = SCC.new(6)
13
+ ```
14
+
15
+ `n` 頂点 `0` 辺の有向グラフを作ります。
16
+
17
+ 頂点番号は、0-based indexです。
18
+
19
+ **制約** `0 ≦ n`
20
+
21
+ **計算量** `O(n)`
22
+
23
+ ## インスタンスメソッド
24
+
25
+ ### add_edge(from, to)
26
+
27
+ ```ruby
28
+ graph.add_edge(1, 4)
29
+ ```
30
+
31
+ 頂点 `from` から頂点 `to` へ有向辺を足します。
32
+
33
+ **制約** `0 ≦ from < n`, `0 ≦ to < n`
34
+
35
+ **計算量** `ならしO(1)`
36
+
37
+ ### scc -> Array[Array[Integer]]
38
+
39
+ ```ruby
40
+ graph.scc
41
+ ```
42
+
43
+ 強連結成分分解して、頂点のグループの配列を返します。
44
+
45
+ 強連結成分分解は、お互いが行き来できる頂点を同じグループとなるように分解します。
46
+
47
+ また、グループの順番は、トポロジカルソートとなっており、頂点uから頂点vに一方的に到達できるとき、頂点uに属するグループは頂点vに属するグループよりも先頭に来ます。
48
+
49
+ **計算量** `O(n + m)` ※ `m` は辺数です。
50
+
51
+ ## Verified
52
+
53
+ [ALPC: G \- SCC](https://atcoder.jp/contests/practice2/tasks/practice2_g)
54
+ - [2538ms 2020/9/8](https://atcoder.jp/contests/practice2/submissions/16569175)
55
+
56
+ # 参考リンク
57
+
58
+ - 当ライブラリ
59
+ - [当ライブラリの実装コード scc\.rb](https://github.com/universato/ac-library-rb/blob/master/lib/scc.rb)
60
+ - [当ライブラリの実装コード scc_test\.rb](https://github.com/universato/ac-library-rb/blob/master/test/scc_test.rb)
61
+ - 本家ライブラリ
62
+ - [本家ライブラリの実装コード scc\.hpp](https://github.com/atcoder/ac-library/blob/master/atcoder/scc.hpp)
63
+ - [本家ライブラリのドキュメント scc\.md](https://github.com/atcoder/ac-library/blob/master/document_ja/scc.md)
64
+ - その他
65
+ - [強連結成分分解の意味とアルゴリズム \| 高校数学の美しい物語](https://mathtrain.jp/kyorenketsu)
@@ -0,0 +1,145 @@
1
+ # Segtree
2
+
3
+ セグメント木です。
4
+
5
+ ## 特異メソッド
6
+
7
+ ### new(arg, e, &op) -> Segtree
8
+
9
+ ```rb
10
+ seg = Segtree.new(arg, e) { |x, y| ... }
11
+ ```
12
+
13
+ 第1引数は、`Integer`または`Array`です。
14
+
15
+ - 第1引数が`Integer`の`n`のとき、長さ`n`・初期値`e`のセグメント木を作ります。
16
+ - 第1引数が長さ`n`の`Array`の`a`のとき、`a`をもとにセグメント木を作ります。
17
+
18
+ 第2引数は単位元`e`で、ブロックで二項演算`op(x, y)`を定義することで、モノイドを定義する必要があります。
19
+
20
+ **計算量** `O(n)`
21
+
22
+ ### モノイドの設定コード例
23
+
24
+ ```ruby
25
+ n = 10**5
26
+ inf = (1 << 60) - 1
27
+
28
+ Segtree.new(n, 0) { |x, y| x.gcd y } # gcd
29
+ Segtree.new(n, 1) { |x, y| x.lcm y } # lcm
30
+ Segtree.new(n, -inf) { |x, y| [x, y].max } # max
31
+ Segtree.new(n, inf) { |x, y| [x, y].min } # min
32
+ Segtree.new(n, 0) { |x, y| x | y } # or
33
+ Segtree.new(n, 1) { |x, y| x * y } # prod
34
+ Segtree.new(n, 0) { |x, y| x + y } # sum
35
+ ```
36
+
37
+ ## インスタンスメソッド
38
+
39
+ ### set(pos, x)
40
+
41
+ ```rb
42
+ seg.set(pos, x)
43
+ ```
44
+
45
+ `a[pos]` に `x` を代入します。
46
+
47
+ **計算量**
48
+
49
+ - `O(logn)`
50
+
51
+ ### get(pos)
52
+
53
+ ```rb
54
+ seg.get(pos)
55
+ ```
56
+
57
+ `a[pos]` を返します。
58
+
59
+ **計算量**
60
+
61
+ - `O(1)`
62
+
63
+ ### prod(l, r)
64
+
65
+ ```rb
66
+ seg.prod(l, r)
67
+ ```
68
+
69
+ `op(a[l], ..., a[r - 1])` を返します。
70
+
71
+ **制約**
72
+
73
+ - `0 ≦ l ≦ r ≦ n`
74
+
75
+ **計算量**
76
+
77
+ - `O(logn)`
78
+
79
+ ### all_prod
80
+
81
+ ```rb
82
+ seg.all_prod
83
+ ```
84
+
85
+ `op(a[0], ..., a[n - 1])` を返します。
86
+
87
+ **計算量**
88
+
89
+ - `O(1)`
90
+
91
+ ### max_right(l, &f) -> Integer
92
+
93
+ ```ruby
94
+ seg.max_right(l, &f)
95
+ ```
96
+
97
+ Segtree上で二分探索をします。
98
+
99
+ ### min_left(r, &f) -> Integer
100
+
101
+ ```ruby
102
+ seg.min_left(r, &f)
103
+ ```
104
+
105
+ Segtree上で二分探索をします。
106
+
107
+ ## Verified
108
+
109
+ - [ALPC: J \- Segment Tree](https://atcoder.jp/contests/practice2/tasks/practice2_j)
110
+
111
+ - [F \- Range Xor Query](https://atcoder.jp/contests/abc185/tasks/abc185_f)
112
+ - xorのセグメントツリーの基本的な典型問題です。FenwickTree(BIT)をxorに改造するだけでも解けます。
113
+ - [ACコード(1538ms)](https://atcoder.jp/contests/abc185/submissions/18746817): 通常のSegtree解。
114
+ - [ACコード(821ms)](https://atcoder.jp/contests/abc185/submissions/18769200): FenwickTree(BIT)のxor改造版。
115
+
116
+ ## 参考リンク
117
+
118
+ - 当ライブラリ
119
+ - [当ライブラリの実装コード segtree.rb](https://github.com/universato/ac-library-rb/blob/master/lib/segtree.rb)
120
+ - [当ライブラリのテストコード segtree.rb](https://github.com/universato/ac-library-rb/blob/master/test/segtree_test.rb)
121
+ - テストコードも具体的な使い方として役に立つかもしれまん。
122
+ - 本家
123
+ - [本家ライブラリのドキュメント segtree.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/segtree.md)
124
+ - [本家のドキュメント appendix.md(GitHub)](https://github.com/atcoder/ac-library/blob/master/document_ja/appendix.md)
125
+ - [本家ライブラリの実装コード segtree.hpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp)
126
+ - [本家ライブラリのテストコード segtree_test.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/unittest/segtree_test.cpp)
127
+ - [本家ライブラリのサンプルコード segtree_practice.cpp(GitHub)](https://github.com/atcoder/ac-library/blob/master/test/example/segtree_practice.cpp)
128
+ - セグメントツリーについて
129
+ - [セグメント木をソラで書きたいあなたに \- hogecoder](https://tsutaj.hatenablog.com/entry/2017/03/29/204841)
130
+
131
+ ## 本家ライブラリとの違い等
132
+
133
+ 基本的に、本家の実装に合わせています。
134
+
135
+ 内部実装に関しても、変数`@d`の0番目の要素には必ず単位元`@e`が入ります。
136
+
137
+ ### 変数名の違い
138
+
139
+ Rubyには`p`メソッドがあるので、引数`p`について、`p`ではなくpositionの`pos`を変数名として使いました。
140
+
141
+ 同様に、本家の変数`size`を、わかりやすさから`leaf_size`としています。
142
+
143
+ ### `ceil_pow2`ではなく、`bit_length`
144
+
145
+ 本家C++ライブラリは独自定義の`internal::ceil_pow2`関数を用いてますが、本ライブラリではRuby既存のメソッド`Integer#bit_length`を用いています。そちらの方が計測した結果、高速でした。
@@ -0,0 +1,105 @@
1
+ # String
2
+
3
+ 文字列`s`の`a`番目から`b-1`番目の要素の`substring`を、`s[a..b)`と表記します。
4
+
5
+ ## suffix_array
6
+
7
+ ```ruby
8
+ (1) suffix_array(s)
9
+ (2) suffix_array(a)
10
+ (3) suffix_array(a, upper)
11
+ ```
12
+
13
+ 長さ`n`の文字列`s`に対し、Suffix Arrayとして長さ`n`の`Integer`の配列を返します。
14
+
15
+ Suffix Array `sa`は`0 ... n`の順列であって、各`i`について`s[sa[i]..n) < s[sa[i+1]..n)`を満たします。
16
+
17
+ このSuffix Arrayの概念は一般の列にも適用でき、`<=>`演算子で比較可能な要素の配列`a`に対しても動作します。
18
+
19
+ 1. `suffix_array(s)`
20
+
21
+ 内部で`s.bytes`によってバイト列に変換します。
22
+
23
+ **制約**
24
+
25
+ - `s`は文字コード255以下の文字のみからなる文字列
26
+
27
+ **計算量**
28
+
29
+ `O(|s|)`
30
+
31
+ 2. `suffix_array(a)`
32
+
33
+ 内部で、いわゆる座標圧縮を行います。要素は大小関係を保ったまま非負整数に変換されます。
34
+
35
+ **制約**
36
+
37
+ - `a`の要素は互いに`<=>`演算子で比較可能
38
+
39
+ **計算量**
40
+
41
+ 要素の比較が定数時間で行えるとして、`O(|a| log |a|)`
42
+
43
+ 3. `suffix_array(a, upper)`
44
+
45
+ **制約**
46
+
47
+ - `a`は`Integer`の配列
48
+
49
+ - `a`の全ての要素`x`について`0≦x≦upper`
50
+
51
+ **計算量**
52
+
53
+ `O(|a| + upper)`
54
+
55
+ ## lcp_array
56
+
57
+ ```ruby
58
+ lcp_array(s, sa)
59
+ ```
60
+
61
+ 長さ`n`の文字列`s`のLCP Arrayとして、長さ`n-1`の`Integer`の配列を返します。`i`番目の要素は`s[sa[i]..n)`と`s[sa[i+1]..n)`のLCP ( Longest Common Prefix ) の長さです。
62
+
63
+ こちらも`suffix_array`と同様一般の列に対して動作します。
64
+
65
+ **制約**
66
+
67
+ - `sa`は`s`のSuffix Array
68
+
69
+ - (`s`が文字列の場合) `s`は文字コード255以下の文字のみからなる
70
+
71
+ **計算量**
72
+
73
+ `O(|s|)`
74
+
75
+ ## z_algorithm
76
+
77
+ ```ruby
78
+ z_algorithm(s)
79
+ ```
80
+
81
+ 入力された配列の長さを`n`として、長さ`n`の`Integer`の配列を返します。`i`番目の要素は`s[0..n)`と`s[i..n)`のLCP ( Longest Common Prefix ) の長さです。
82
+
83
+ **制約**
84
+
85
+ - `s`の要素は互いに`==`演算子で比較可能
86
+
87
+ **計算量**
88
+
89
+ `O(|s|)`
90
+
91
+ <hr>
92
+
93
+ ## Verified
94
+
95
+ - suffix_array, lcp_array
96
+ - [I - Number of Substrings](https://atcoder.jp/contests/practice2/tasks/practice2_i)
97
+ - [AC 1362 ms](https://atcoder.jp/contests/practice2/submissions/17194669)
98
+
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
+ ## 参考
104
+
105
+ - [本家ACLのドキュメント String](https://atcoder.github.io/ac-library/master/document_ja/string.html)
@@ -0,0 +1,87 @@
1
+ # 2-SAT
2
+
3
+ 2-SAT を解きます。変数 x_0, x_1, ..., x_N-1 に関して、
4
+
5
+ (x_i = f) ∨ (x_j = g)
6
+
7
+ というクローズを足し、これをすべて満たす変数の割当があるかを解きます。
8
+
9
+ **エイリアス**
10
+
11
+ - `TwoSAT`
12
+ - `TwoSat`
13
+
14
+ <hr>
15
+
16
+ ## 特異メソッド
17
+
18
+ ### new(n = 0) -> TwoSAT
19
+
20
+ ```ruby
21
+ ts = TwoSAT.new(n)
22
+ ```
23
+
24
+ n 変数の 2-SAT を作ります。
25
+
26
+ **計算量**
27
+
28
+ - `O(n)`
29
+
30
+ <hr>
31
+
32
+ ## インスタンスメソッド
33
+
34
+ ### add_clause(i, f, j, g) -> nil
35
+
36
+ `i: Integer`, `f: bool`, `j: Integer`, `g: bool`
37
+
38
+ ```ruby
39
+ ts.add_clause(i, true, j, false)
40
+ ```
41
+
42
+ (x_i = f) ∨ (x_j = g) というクローズを足します。
43
+
44
+ **計算量**
45
+
46
+ - ならし `O(1)`
47
+
48
+ ### satisfiable? -> bool
49
+
50
+ ```ruby
51
+ ts.satisfiable?
52
+ ```
53
+
54
+ 条件を満たす割当が存在するかどうかを判定します。割当が存在するならば `true`、そうでないなら `false` を返します。
55
+
56
+ **エイリアス**
57
+
58
+ - `satisfiable?`
59
+ - `satisfiable`
60
+
61
+ **計算量**
62
+
63
+ - 足した制約の個数を `m` として `O(n + m)`
64
+
65
+ ### answer -> Array[bool]
66
+
67
+ ```ruby
68
+ ts.answer
69
+ ```
70
+
71
+ 最後に呼んだ `satisfiable?` のクローズを満たす割当を返します。
72
+ `satisfiable?` を呼ぶ前や、`satisfiable?` で割当が存在しなかったときにこの関数を呼ぶと、長さ n の意味のない配列を返します。
73
+
74
+ **計算量**
75
+
76
+ - `O(n)`
77
+
78
+ <hr>
79
+
80
+ ## Verified
81
+
82
+ - [H - Two SAT](https://atcoder.jp/contests/practice2/tasks/practice2_h)
83
+ - [163 ms](https://atcoder.jp/contests/practice2/submissions/16655036)
84
+
85
+ ## 参考
86
+
87
+ [本家 ACL のドキュメント 2-SAT](https://atcoder.github.io/ac-library/master/document_ja/twosat.html)