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.
- checksums.yaml +7 -0
- data/.github/workflows/unittest.yml +16 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +198 -0
- data/Gemfile +3 -0
- data/LICENSE +116 -0
- data/README.ja.md +56 -0
- data/README.md +41 -0
- data/Rakefile +11 -0
- data/ac-library-rb.gemspec +32 -0
- data/bin/console +8 -0
- data/bin/lock_lib.rb +27 -0
- data/bin/setup +8 -0
- data/document_en/binary_index_tree.md +3 -0
- data/document_en/convolution.md +67 -0
- data/document_en/dsu.md +132 -0
- data/document_en/fenwick_tree.md +99 -0
- data/document_en/index.md +79 -0
- data/document_en/lazy_segtree.md +141 -0
- data/document_en/math.md +104 -0
- data/document_en/max_flow.md +165 -0
- data/document_en/min_cost_flow.md +132 -0
- data/document_en/modint.md +263 -0
- data/document_en/priority_queue.md +119 -0
- data/document_en/segtree.md +134 -0
- data/document_en/string.md +106 -0
- data/document_en/two_sat.md +91 -0
- data/document_en/union_find.md +3 -0
- data/document_ja/convolution.md +64 -0
- data/document_ja/dsu.md +183 -0
- data/document_ja/fenwick_tree.md +83 -0
- data/document_ja/index.md +89 -0
- data/document_ja/lazy_segtree.md +135 -0
- data/document_ja/math.md +116 -0
- data/document_ja/max_flow.md +129 -0
- data/document_ja/min_cost_flow.md +105 -0
- data/document_ja/modint.md +349 -0
- data/document_ja/priority_queue.md +103 -0
- data/document_ja/scc.md +65 -0
- data/document_ja/segtree.md +145 -0
- data/document_ja/string.md +105 -0
- data/document_ja/two_sat.md +87 -0
- data/lib/ac-library-rb/version.rb +3 -0
- data/lib/convolution.rb +124 -0
- data/lib/core_ext/modint.rb +19 -0
- data/lib/crt.rb +52 -0
- data/lib/dsu.rb +44 -0
- data/lib/fenwick_tree.rb +48 -0
- data/lib/floor_sum.rb +21 -0
- data/lib/inv_mod.rb +26 -0
- data/lib/lazy_segtree.rb +149 -0
- data/lib/lcp_array.rb +23 -0
- data/lib/max_flow.rb +137 -0
- data/lib/min_cost_flow.rb +143 -0
- data/lib/modint.rb +170 -0
- data/lib/pow_mod.rb +13 -0
- data/lib/priority_queue.rb +89 -0
- data/lib/scc.rb +77 -0
- data/lib/segtree.rb +140 -0
- data/lib/suffix_array.rb +128 -0
- data/lib/two_sat.rb +34 -0
- data/lib/z_algorithm.rb +32 -0
- data/lib_helpers/ac-library-rb/all.rb +22 -0
- data/lib_lock/ac-library-rb.rb +22 -0
- data/lib_lock/ac-library-rb/convolution.rb +126 -0
- data/lib_lock/ac-library-rb/core_ext/modint.rb +19 -0
- data/lib_lock/ac-library-rb/crt.rb +54 -0
- data/lib_lock/ac-library-rb/dsu.rb +46 -0
- data/lib_lock/ac-library-rb/fenwick_tree.rb +50 -0
- data/lib_lock/ac-library-rb/floor_sum.rb +23 -0
- data/lib_lock/ac-library-rb/inv_mod.rb +28 -0
- data/lib_lock/ac-library-rb/lazy_segtree.rb +151 -0
- data/lib_lock/ac-library-rb/lcp_array.rb +25 -0
- data/lib_lock/ac-library-rb/max_flow.rb +139 -0
- data/lib_lock/ac-library-rb/min_cost_flow.rb +145 -0
- data/lib_lock/ac-library-rb/modint.rb +172 -0
- data/lib_lock/ac-library-rb/pow_mod.rb +15 -0
- data/lib_lock/ac-library-rb/priority_queue.rb +91 -0
- data/lib_lock/ac-library-rb/scc.rb +79 -0
- data/lib_lock/ac-library-rb/segtree.rb +142 -0
- data/lib_lock/ac-library-rb/suffix_array.rb +130 -0
- data/lib_lock/ac-library-rb/two_sat.rb +36 -0
- data/lib_lock/ac-library-rb/z_algorithm.rb +34 -0
- 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)
|
data/document_ja/scc.md
ADDED
@@ -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)
|