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,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)