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

計算量の話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Catupper Catupper
September 16, 2013
1.1k

 計算量の話

競プロの第一歩

Avatar for Catupper

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 頂点の数) – 単一始点最短経路のアルゴリズム – 負閉路があると動かない