概要 †
- プロコンで必要となる知識のまとめ。
- 特にこのページはアルゴリズムのまとめ。
- アルゴリズムが判ってない、計算量が判ってないから、「○○は遅いからダメ」みたいなのをあらゆる状況で言っちゃう人は割と多い。必要なところだけ早くすればいい。
- 以下の問題を何とかしたいから勉強しているのだけど、キリがないという気分
- 正しいと信じてるプログラムが間違ってるケースを減らしたい
- 脳内でこうやればできる、というところと実装の溝を減らしたい。実装を単純作業にしたい
- トップレベルの人でも普通知らない、非自明かつ一般的なアルゴリズムを使えるようになりない
- 典型なのに知らずに解けないケースを減らしたい
記録 †
下位ページ †
目次 †
練習方法 †
- 解いた問題数を増やすのは良い事なんだけど、解いた問題数を増やすためだけに、簡単な問題を解きまくるのってすげえ時間の無駄
- Codeforces
- 黄色の人とかがCFのBCD埋めるのは典型力と非典型力と実装力が程よくついていいと思うけどE埋めは本当に虚無なのでやめた方がいいと思う
- Eには典型重実装がたくさんあって不毛
- AOJ-ICPC
- 多くの人にはオススメできない気がしてきました。
- 自分はすごい実力ついたと思っていたけれど、赤になってから実装力不足が目立ち始めたから始めただけ
- 赤になるまでは質の高い問題をひたすら解くべき
参考 †
勉強すべきこと †
重要 †
- Cartesian Tree
- monge
- ウェーブレット木
- 動的ウェーブレット木
- 永続ウェーブレット木
- 動的永続ウェーブレット木
- ウェーブレット行列
- Blackbox Algebra
- Link-Cut Tree(木で最強)
- インタバル木
- Dancing Links
- マージ可能ヒープ
- skew, 乱択、フィボナッチ、Pairingソートなど
- 分割統治法,逐次構成法,
- 平面走査法
- Gray Code
- 永続
- 動的
- セグメントツリー
- 遅延セグメントツリー
- 永続遅延セグメントツリー
- しゃくとり法
- ベルマンフォードって何のために使うの?(LatteさんのSelf-constructing witchが1つの解答になるかも)
- AhoCorasick?
そこそこ †
- カタラン数
- 山登り法
- マルチスタートローカルサーチ(ローカルサーチのスタート地点を複数点設けます)
- 焼き鈍し法
- 遺伝的アルゴリズム
- タブーサーチ
- モンゴメリ乗算
- 高速アダマール変換
- 区間ふるい
- MCS
- DM分解
どうでもいい †
- ADS
- 2-SAT
- Treap, RBST(k-th tree), 平衡二分木
- デク・優先度付キュー
- ボロノイ図とデローネイ三角形分割
- 美術館問題
- 最短路問題
- 埋め込み
- Stern-Brocot木
- ベルヌーイ数列挙 O(n^2)
- 分割数 O(n√n)
- スターリング数 O(n^2)
- Chordal graph
- Cograph
- Stoer-Wagner
- 永持-茨木法 (全点対最小カット)
- 有向木の部分木のハッシュ
- Knuth-Morris-Pratt
- Aho-Corasick
- CIPR (最長共通部分列)
- 編集距離 O(nm)
- 部分回文列挙
- Segment Treeでローリングハッシュ
- Segment treeでflip/count: !libuwi/utils/structure/segtree/SegmentTreeRXQ.java
- Segment treeで点更新・範囲le/geカウント
- Skip List
- Van Emde Boas tree (vEB tree)
- Fixed Universe Structures
- 永続的平衡2分探索木
- BK-tree
- Trie
- Meldable heap
- 削除・更新のできる2分ヒープ
- Double-ended priority queue
- キュー with minimum
- Shunting-yard algorithm
- 平面グラフ 双対なものが構成できる。
- 木について
(1) 頂点uの値をxに変える
(2) 頂点u, vを結ぶ最短パスの頂点のうち、最小値を答える
というクエリを、O(log n)で処理できないという結論に至った。(今の僕には)
ライブラリ †
- はむこのライブラリ
- TODO
- エラトステネスのかわりに区間篩を使って実装。
- 区間篩じゃないとかなり大きい範囲の素数全列挙はできないという噂
アルゴリズム | 概要 | 計算量 |
Johnson | | 前処理 O(V E). 中間処理 O(V E log V). 後処理 O(V^2). |
Warshall Floyd | 全点から全点への最小コスト。 | O(V^3)、だが漸化式が単純なので速い。 |
Dijkstra | 1点から全点への最小コスト。コストは正でなければならない。 | O(E log V) |
K Shortest | | O(k E log V) |
Prim | 最小重み無向全域木=重みつき無向グラフの全域木の中で、重みが最小のものを求める。根は指定する。 | O(E log V) |
Cuninghame-Green | 最小直径無向全域木=重みつき無向グラフの全域木の中で,直径が最小のものを求める | 前処理O(V^3), 端点計算O(VE) |
Chu-Liu/Edmond | 最小重み有向全域木=重み付き有向グラフの全域木の中で、重みが最小のものを求める。根は指定する。 | O(VE) |
Dreyfus-Wagner | 最小重みシュタイナー木=頂点群Tを通る木の中で、重みが最小のものを求める。 | t=11が限界。時間O(n 3^t + n^2 2^t + n^3).空間計算量 O(n 2^t). |
Edmonds-Karp | 有向最大流 | O(E^2 V) |
Goldberg-Tarjan | 有向最大流 | O(V^2 sqrt(E)) |
Nagamochi-Ibaraki | 無向グラフ最小カット | O(VE + V log V) |
Gomory-Hu | 最大流 | O(V MAXFLOW) |
木の高さの最大値 | 木の直径が最小になるような根を計算 | O(E) |
Double Sweep=木の直径 | 葉と葉の最大距離を計算 | O(E) |
有向オイラー路存在判定 | すべての辺をちょうど一度通る閉路があるか判定 | O(E) |
無向オイラー路存在判定 | すべての辺をちょうど一度通る閉路があるか判定 | O(E) |
無向中国人郵便配達問題 | | O(o m log n + o^2 2^o), o=18が限度 |
最短ハミルトン路 | すべての頂点をちょうど一度通る閉路を求める。判定もNP困難。 | O(V^2 2^V), V=18が限度。全探索はO(V!)なので少し落ちてる |
レンジ木 | | |
Splay木 | 平衡二分木 | |
Interval Tree | | |