ac-library-rb 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|