Upgrade to Pro — share decks privately, control downloads, hide ads and more …

計算量の話

Catupper
September 16, 2013
1.1k

 計算量の話

競プロの第一歩

Catupper

September 16, 2013
Tweet

Transcript

  1. 例 • 問:1 ~ Nまでの整数の総和を求めよ – 普通に計算する → N-1回足し算 →

    O(N-1) – 公式を使う → 足し算と掛け算と割り算 → O(3) • 計算の仕方によって計算量が違うことがある
  2. いくつかのルール • O記法の中身は一番大きな規模だけ残す • 係数は1にする • 例 – O(N-1) →

    O(N) – O(4N^2 + 2N) → O(N^2) – O(N^2 + M^2) → NとMが独立なのでこれ以上無理 – O(2^N + N^2) → O(2^N) – O(3) → O(1)
  3. なぜか • 中の変数が非常に大きな値になった時のことを考える • O(5N^2 + 100N + 4)の場合 –

    N = 1 → 109 – N = 100→ 60004 – N = 10000 → 501000004 – N = 100000000 → 50000010000000004 • ほとんどO(5N^2)と変わらなくなる • O(N^2)との相対誤差は常にたったの5だから無視できる
  4. そんなのありかよ • 素数表をあらかじめ用意しておく – O(1) – 柔軟な発想である • しかし欠点がある –

    素数表は非常に大きくなる – 少なくとも予想されるNより小さい整数について知っ て居る必要がある – ようは覚えるためにメモリをめっちゃ食う
  5. まとめ • どれくらい計算に時間かかるか – 時間計算量 • どれくらい計算にメモリを食うか – 空間計算量 •

    これらを考えると、そのアルゴリズムが問題を解くのに 適しているかどうか決める目安になる
  6. 制限からの計算量予想 • N 10^6 → O(N) ≦ もしくは O(N log

    N) • N 10^5 → O(N log N) ≦ もしくは O(N log^2 N) • N 3000 → O(N ^ 2) ≦ • N 500 → O(N ^ 3) ≦ の中でも早いもの • N 100 → O(N ^ 3) ≦ • N 50 → O(N ^ 5) ≦ くらいまでいける • N 20 → O(2 ^ N) ≦ もしくは O(N * 2 ^ N)
  7. O(N) • 1~Nまでの数字の逆元の取得 – inv[x] = -inv[MOD % x] *

    (MOD / x); – という漸化式を使う方法 – 組み合わせ関係の式の前処理において多用 • aho corasick法による文字列探索 – 探索対象文字列から文字列群の各要素を検出するアル ゴリズム
  8. O(N) • グラフの閉路判定 – 無向グラフの木状判定、有向グラフのDAG判定 – DFSするだけ • グラフの強連結成分分解 –

    強連結成分とはその中でどの頂点対間にも両方向にパ スがある誘導グラフ – 強連結成分を圧縮するとDAGになる
  9. O(N) • DAGのトポロジカルソート – 辺が全て小さい番号から大きい番号に伸びているよう に頂点を番号付けする – O(辺の数)です • DAGに変換した後にDP

    – あらゆるDPはDAGの問題に変換可能です – 変換後の辺の数をNとするとそのDPはO(N)で溶ける 可能性が高いです
  10. O(N^2) • 全頂点対の走査 – グラフを作る段階に行う、あらゆるアルゴリズム – 平面上の全頂点間の辺の列挙等 • ベルマンフォード法 –

    単一始点最短経路を求めるアルゴリズム – 負の閉路があっても大丈夫 – 特殊な線形計画問題の双対である(牛ゲー)
  11. O(log N) • 二分探索 – 答えが探索範囲の中点についてどちら側にあるか調べ る方法を繰り返す探索方法 • ユークリッドの互除法 –

    最大公約数をもとめたり、逆元を求めたりできる • 繰り返し2乗法 – X^NをO(log N)でもとめる – 行列に使えば、漸化式を高速に解いたりできる
  12. O(log N) • std:set, std:map, std:priority_queueのクエリ – C++のライブラリから得られる便利なデータ構造 – 順序付き集合、辞書、順序付きキュー

    • 平衡二分探索木のクエリ – 探索、質問、更新、追加、削除、併合、分割 – 右に行くほど実装が重い
  13. O(NlogN) • ダイクストラ法 – 本当はO((辺の数 + 頂点の数) log 頂点の数) –

    単一始点最短経路のアルゴリズム – 負閉路があると動かない • エンベロープによる走査 – 複数の一次式に対して、最小値や最大値をなぞる方法 – グラフの下端や上端をなぞる感じ
  14. O(NlogN) • ソート – データを順序付きに並び替えること – 超頻出アルゴリズム • ダイクストラ法 –

    本当はO((辺の数 + 頂点の数) log 頂点の数) – 単一始点最短経路のアルゴリズム – 負閉路があると動かない