SlideShare a Scribd company logo
1 of 73
Download to read offline
2010/03/20 NTTデータ駒場研修所 (情報オリンピック春合宿)




   プログラミングコンテストでの
        データ構造
              秋葉 拓哉 / (iwi)
内容
• Union-Find 木
• バケット法と平方分割
• セグメント木

• 共通点:自分で実装するデータ構造
• セグメント木が中心
 – IOI でのセグメント木の出題が非常に多い
グループを管理する

UNION-FIND 木
Union-Find 木の機能
• グループ分けを管理する
• はじめ,n 個の物は全て別々のグループ


   1     2    3   4      5


• 次の 2 種類のクエリに対応する
 – 「まとめる」と「判定」
クエリ 1:まとめる
• 2 つのグループを 1 つにまとめる


  1   2     1   3       2   4   6




  1   2     1   2   3       4   6
クエリ 2:判定
• 2 つの要素が同じグループに属しているかを
  判定する


   1   3      2    4       6   5



           1 と 3 → true
           1 と 2 → false
素朴な実現法 (1/2)
• 配列に,同じグループなら同じ数字を入
  れておく


   1   3       2   4   6       5



   1       2   3   4       5   6
   1       2   1   2       5   2
素朴な実現法 (2/2)
• この方針の問題点
 – グループをまとめる際に,O(n) 時間かかって
   しまう
 – 実際には,この方針でも少しの工夫でならし O(log n) 時間にできます




• Union-Find 木は,もっと効率的に行う
Union-Find 木
• グループを,1 つの木で表現する
 – したがって,全体では森

    1       3   2       4       6   5



        1               2           5

        3           4       6
まとめる
• 片方の木の根からもう片方の根に辺を張
  ればよい
                 1       2
     1       2   3   4       6


                     2
         1
                 1   4   6
         2
                 3
判定
• 2 つの要素を上に辿って,根が同じかどう
  かを見ればよい

      1           2        5

      3       4       6


     2 と 6 → 根は共に 2 → true
     1 と 4 → 根は 1 と 2 → false
工夫 1:経路圧縮
• 上向きに辿って再帰的に根を調べる際に,調
  べたら辺を根に直接つなぎ直す
           1

           2              1

           3          2   3      4
           4
• 4 の根を調べると,2, 3, 4 の根が 1 と分かる
工夫 2:ランク
• 木の高さを持っておき,低い方を高い方
  に繋げるようにする
     ランク 3   ランク 2

       1      4          1

       2      5      2       4

       3             3       5
• ただし,経路圧縮と組み合わせた際,経路圧縮による高
  さの変化は気にしない
Union-Find 木の計算量
• 2 つの工夫の両方をして O(α(n))
 – α(n) はアッカーマン関数 A(n, n) の逆関数
 – 相当小さく,ほぼ定数


• 片方だけでも,だいたい O(log n)
 – 経路圧縮のみが実装が楽でよい

• これらはならし計算量
Union-Find 木の実装 (1/3)
• 経路圧縮のみ(ランクは使わない)

 int par[MAX_N];        // 親の番号

 // n 要素で初期化
 void init(int n) {
      for (int i = 0; i < n; i++) par[i] = i;
 }



• par[i] = i ならば根
    – はじめは全部の頂点が根
Union-Find 木の実装 (2/3)
// 木の根を求める
int find(int x) {
   if (par[x] == x) {                  // 根
       return x;
   } else {
       return par[x] = find(par[x]);   // 経路圧縮
   }
}

// x と y が同じ集合に属するか否か
bool same(int x, int y) {
   return find(x) == find(y);
}
Union-Find 木の実装 (3/3)

// x と y の属する集合を併合
void union(int x, int y) {
   x = find(x);
   y = find(y);
   if (x == y) return;

    par[x] = y;
}
補足
• Union-Find 木はグループをまとめることは
  できても,分割することはできない
 – 重要な制約


• Union-Find 木を改造して機能を付加するこ
  とが必要になるような問題もある
√n を上手く使う

バケット法と平方分割
バケット法とは
• 列や平面を「バケット」に分割して管理

• 列                 ・・・


       バケット

• 平面
                   ←点




          バケット →
平方分割とは (1/2)
• バケット法の,列に関する特殊な場合

• n 個の列を √n 程度の大きさのバケットに
  分けて管理する

 – 各バケットに含まれる要素 √n 個
 – バケットの個数も √n 個
    これらより良い性質が生まれる
平方分割とは (2/2)
• 各バケットにどのようなデータを持って
  おくかによって様々な機能を実現できる

• 応用力が非常に高い
 – 逆に言えば,自分で考える部分が大きい
Range Minimum Query (RMQ) 問題

• n 個の数の列 a1, a2, ..., an があります

• 以下の 2 種類のクエリを高速に処理せよ
  1. 区間 [i, j] に含まれる最小の数字を答えよ
  2. ai を x に変更せよ


    これを,平方分割でやってみよう
平方分割による RMQ (1/5)
• 前処理
 – b = floor(√n) とし,列 a を b 個ごとのバケット
   で扱う
 – 各バケットでの最小値を計算しておく


  1 3 2 6 7 4 3 0 8 4 3 5 9 2 1 5
     1       0       3       1
              n=16 での例
平方分割による RMQ (2/5)
• 区間 [i, j] の最小値を求めるクエリ
 – 区間に完全に含まれるバケット
   • そのバケットの最小値
 – はみ出した要素
   • 個々の値

  1 3 2 6 7 4 3 0 8 4 3 5 9 2 1 5
     1       0       3       1
    2, 6, 0, 3, 9, 2 の min を計算すればよく, 0
平方分割による RMQ (3/5)
• バケットの数,はみ出した要素の数が共
  に √n 程度で抑えられる
 – バケットの数はそもそも √n 個程度
 – はみ出した要素も 2√n より少ない


  1 3 2 6 7 4 3 0 8 4 3 5 9 2 1 5
     1       0       3       1
   2, 6, 0, 3, 9, 2 の min を計算すればよく, 0
平方分割による RMQ (4/5)
• ai の値を x に更新するクエリ

• 要素の値を更新
• ai を含むバケットの最小値を更新
 – バケットに含まれる値を全部見ても √n 個

• データの持ち方を工夫すればこの部分はもっと効率よくできますが,
  最小値の計算が O(√n) なのでこれで十分
平方分割による RMQ (5/5)
• 以上で,
 – 前処理 O(n)
 – 各クエリ O(√n)
 で RMQ が実現できた

• あくまで例であって,実際に RMQ が必要になった際に平方分割を
  実装することはあまりないはず
応用
• 各バケットが,値ではなく別のデータ構
  造を持つ平方分割がしばしば出題
 – 各バケットが二分探索木を持ったり
 – 各バケットが Binary Indexed Tree を持ったり


このような場合バケットの大きさは √n 丁度でなく,そ
れらのデータ構造の処理の計算量をあわせて調整する
補足 (1/3)
• 平方分割は,√n 分木と解釈することもで
  きる




    上が親,下が子と見れば,3 (=√9) 分木
補足 (2/3)
• 「平方分割」は余りポピュラーでない
 – 「“平方分割” に一致する日本語のページ 10 件」
 – 平方根分割の方が正しいのでは?
 – 「 "平方根分割" に一致する日本語のページ 2 件」


• 「sqrt decomposition」ってロシアの人が書
  いてた
 – 「“sqrt decomposition”の検索結果 1 件」
補足 (3/3)
• 実装時には,バケットのサイズは最大 n
  でのものに固定してしまってよい
 – 例えば,n 最大 10000 なら 100 に固定


• バケット法に限らず,√n という値を上手
  く使うと効率的になる場合がある
 – IOI ‘09 Regions
区間を上手に扱うための木

セグメント木とは
セグメント木とは (1/2)
• 各ノードが区間に対応づいた完全二分木
 – 子は親を半分にした区間を持つ

                                           [1, 8]

                 [1, 4]                                              [5, 8]

        [1, 2]                [3, 4]                    [5, 6]                [7, 8]

    1        2            3            4            5            6            7        8

                          長さ 8 の区間での例
セグメント木とは (2/2)
平方分割と同様に

• 各ノードにどのようなデータを持ってお
  くかによって様々な機能を実現できる

• 応用力が非常に高い
 – 逆に言えば,自分で考える部分が大きい
Range Minimum Query (RMQ) 問題
• n 個の数の列 a1, a2, ..., an があります

• 以下の 2 種類のクエリを高速に処理せよ
  1. 区間 [i, j] に含まれる最小の数字を答えよ
  2. ai を x に変更せよ

  これを,セグメント木でやってみよう
       まずは,処理のイメージについて説明し,
        後で細かい実装について話します.
セグメント木による RMQ (1/4)
• 方針
 – 各ノードに,対応づいた区間の最小値を持つ

                                   1

                   3                               1

           3               7               1               2

       5       3       7       9       1       4       6       2

       5       3       7       9       1       4       6       2
セグメント木による RMQ (2/4)
• 初期化
 – 子ノードから順に,再帰的に, O(n)
 計算量に余裕があれば初期化時は全てのノードを INT_MAX 等にしてしまってもよい


                                1

                3                               1

        3               7               1               2

    5       3       7       9       1       4       6       2

    5       3       7       9       1       4       6       2
セグメント木による RMQ (3/4)
• 区間 [i, j] の最小値を求めるクエリ
 – 完全に区間に含まれるできるだけ大きい区間
   で「受け止める」イメージ
                               1

               3                               1
                                                               3と1と6の
       3               7               1               2       最小値 = 1 が
                                                               [1, 7] の最小値
  5        3       7       9       1       4       6       2

   5       3       7       9       1       4       6       2
セグメント木による RMQ (4/4)
• ai の値を x に更新するクエリ
 – ai を含む区間のノード全てについて,値を計
   算しなおす
                                   1

                 3→2                                   1

       3→2                 7                   1                   2

     5→2   3       7           9           1       4           6       2

    5→2      3         7       9       1           4       6           2
セグメント木による RMQ の計算量
• 共に,各高さで定数個のノードにしかア
  クセスせず,O(log n)
 – この 2 種類の処理のタイプが,RMQ に限らず,
   セグメント木の処理の基本

                             1                                                                 1


             3                               1                               3→2                               1


     3               7               1               2             3→2                 7               1               2


 5       3       7       9       1       4       6       2   5→2         3         7       9       1       4       6       2



                 区間に対する処理                                                     点に対する処理
セグメント木の重要な利点
• 平衡処理が必要ない
 – セグメント木でなく,普通の二分木でも出来
   る物は結構ある
 – しかし,普通の二分木でやると,平衡処理が
   必要になる
  • あるいは,そうでなくても,実装量はセグメント
    木のほうが抑えられる場合が多い
Tips
• 前処理や空間計算量(ノードの個数)
 – × O(n log n)
 – ○ O(n)
   • n + n/2 + n/4 + n/8 + ... < 2n
初心者にオススメの実装方法

セグメント木の実装
セグメント木の実装
• 木を実装するというと,結構大変そう
 – 情報オリンピックでは,そこまで急ぐ必要も
   ない
 – その場で気合で考えても,多分何とかなる
 – しかし,簡単に実装できるに越したことはな
   いし,複雑なプログラムではバグも出やすい

• オススメの実装方法を一通り紹介
 – RMQ を実装します
木の持ち方
• ノードに番号を付ける
 – ポインタによる表現でなく,配列で持つ


• 上の段から,同じ段では左から順に番号
  をふる
ノードの番号付けの例
                             0                                                                   1

            1                                  2                                 3                               1

    3               4                 5                 6                3               7               1               2

7       8       9       10       11       12       13       14       5       3       7       9       1       4       6       2

                        番号付け                                                         ノードの持つ値




                0       1    2        3    4       5        6    7   8       9   10 11 12 13 14
                1       3    1        3    7       1        2    5   3       7       9   1       3   6       2

                                      プログラム上での表現(配列)
木のプログラム上での宣言

const int MAX_N = 131072;

int n;                          // n は 2 のべき乗
int dat[MAX_N * 2 - 1];

// 初期化
void init() {
     // 全ての値を INT_MAX に
     for (int i = 0; i < 2 * n - 1; i++) dat[i] = INT_MAX;
}



                ノードの個数は n + n/2 + n/4 + ... = 2n - 1
この番号付けの性質
• 番号 n のノード
                                                   0

                                  1                                  2
 – 親:(n-1)/2(を切り捨て)
                          3               4                 5                 6

 – 子:2n + 1,2n + 2    7       8       9       10       11       12       13       14




• 簡単に親や子にアクセスできる

• この番号付けが上手く働くのは,セグメント木が完全二
  分木だから
値の更新 (再)
• ai の値を x に更新
 – ai を含む区間のノード全てについて,値を計
   算しなおす
                                    1

                  3→2                                   1

        3→2                 7                   1                   2

      5→2   3       7           9           1       4           6       2

     5→2      3         7       9       1           4       6           2
値の更新の実装
• 場所 i に対応する一番下(葉)のノードの
  番号は,n + i -1
• そこから,親へ辿ればよい
                                0                                   (1-1) / 2 = 0

               1                                  2                 (4-1) / 2 = 1

       3               4                 5                 6        (9-1) / 2 = 4

   7       8       9       10       11       12       13       14   8+2–1=9

                   n = 8,i = 2 の場合
値の更新の実装
// i 番目の値 (0-indexed) を x に変更
void update(int i, int x) {
      // 葉のノードの番号
      i += n - 1;
      dat[i] = x;
      // 登りながら更新
      while (i > 0) {
            i = (i - 1) / 2;
            dat[i] = min(dat[i * 2 + 1], dat[i * 2 + 2]);
      }
}
最小値の取得 (再)
• 区間 [i, j] の最小値を求めるクエリ
 – 完全に区間に含まれるできるだけ大きい区間
   で「受け止める」イメージ
                               1

               3                               1
                                                               3と1と6の
       3               7               1               2       最小値 = 1 が
                                                               [1, 7] の最小値
  5        3       7       9       1       4       6       2

   5       3       7       9       1       4       6       2
最小値の取得の実装
• より形式的には,再帰的に
 – 区間 [i, j] とそのノードの区間が全く交差しな
   い
  • INT_MAX でも返しておく
 – 区間 [i, j] がそのノードの区間を完全に含む
  • その節点の持つ値を返す
 – どちらでもない
  • 2 つの子ノードについて再帰的に計算
  • その 2 つの値の最小値を返す
区間に対する処理の実装
• ノードの番号から,そのノードに対応づいて
  いる区間を知りたい

• 3 つの方法
 1. 頑張って計算する
 2. 予め全てのノードについて求めておく
 3. 再帰関数の引数にしてしまう

 3 が楽なのでオススメです
最小値の取得の実装
// [a, b) の最小値,l, r にはノード k に対応づく区間を与える
int query(int a, int b, int k, int l, int r) {
      if (r <= a || b <= l) return INT_MAX;                 // 交差しない?
      if (a <= l && r <= b) return dat[k];                  // 完全に含む?
      else {
             int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
             int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
             return min(vl, vr);
      }
}


       外からは query(a, b, 0, 0, n) のように呼ぶ
(ここまで閉区間で説明してきたが,関数は半開区間なことに注意)
Tips
• 実際には,この実装なら n が 2 の累乗でな
  くても動作する
 – 値の更新の方はこのままではダメで,同様の
   手法で再帰関数で書けば OK


• ただし,配列サイズは MAX_N * 2 - 1 では
  足りない
 – MAX_N * 4 取れば十分
セグメント木に関する補足
区間の扱い
• セグメント木では,区間を考える際に半
  開区間で考えると都合が良い
 – [i, j) ・・・ i, i+1, ..., j-1
 – [l, r) に対応するノードの子ノードは?
   • m = (l + r) / 2 として,[l, m),[m, r)


• セグメント木に限らず,半開区間を使う
  とわかりやすい場合は多い
より複雑なセグメント木
• 条件を満たす最長の区間の長さが得たい
 – というようなクエリがたまにある
 – 例:0 になっている最長の区間の長さ

• 各ノードについて,
 – そこに含まれる最長の区間の長さ
 – 左側に繋がる部分の長さ
 – 右側に繋がる部分の長さ
• を持つようにすれば効率的に出来る
より高速な実装
• 区間に対する処理も再帰しないように実
  装すると,より高速になる

• データ構造に関する問題は,実行時間制
  限が厳しい場合が少なくない
 – 平方分割による解法を落としたい,等
 – まずはテストをする
平方分割 vs セグメント木
• 共に,応用力の高いデータ構造

• セグメント木
 – 同じものが実現できれば,平方分割より高速


• バケット法
 – ソースコードや考えることがシンプルで済む
 – セグメント木よりさらに応用力が高い
セグメント木を使う問題たち

セグメント木の使われ方
セグメント木の出番
• 主に,以下の 3 種類に分けられる

1. クエリ系の問題
 – データ構造を直接的に聞いてきている
 – 比較的考えやすい
2. (平面)走査系の問題
3. DP 等の計算を加速する問題
走査系の問題
• セグメント木を持ちながら平面上をス
  キャンする,等




 – IOI’08 Pyramid Base,春合宿’09 Starry Sky
DP 等の計算を加速
• 例:漸化式に区間の min が入っている
 – IOI ‘09 Salesman


• DP の方針をまず考えて
 – 「こんな処理が高速にできれば高速になる」
 – クエリの問題に帰着し,データ構造を考える
補足
Binary Indexed Tree
           (Fenwick Tree)
• 列で,以下の操作が行えるデータ構造
 – i 番目の要素 ai に値を x 加える
 – i 番目までの数の和を計算する
  • a1 + a2 + ... + ai
  • 引き算すれば ai + ai+1 + ... + aj が計算できる

• 非常に簡単に実装できる
 – セグメント木でも同様の機能が実現可
• 是非調べてみて下さい
Binary Indexed Treeと
           セグメント木
• BIT はセグメント木から要らないノードを
  削除した物と考えることもできる

                    8

            4

        2                   6

    1           3       5       7
領域木 (Range Tree)
• セグメント木のノードに二分探索木や配
  列を持つ
 – 2 次元の長方形領域に対するクエリに対応
 – セグメント木の入れ子を増やせば,より高次
   元にできる

• 滅多にお目にかかりませんが,データ構造が好きな IOI
  なら・・・?と密かに思っています.
おわりに (1/2)
• データ構造を勉強する
 – 何ができるのか
 – どうやって作るか
      • STL にあるなら,どうやって使うか


• 重要なデータ構造
 –   キュー,スタック,デク
 –   二分探索木,順位キュー
 –   Union-Find
 –   Binary Indexed Tree,Segment Tree
おわりに (2/2)
• セグメント木,領域木などのデータ構造
  は,普通のアルゴリズムとデータ構造の
  本には載っていない

• 計算幾何学の本に載っています
おわり

お疲れ様でした

More Related Content

What's hot

様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題tmaehara
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化yosupo
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』Proktmr
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解くshindannin
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 
AtCoder Beginner Contest 015 解説
AtCoder Beginner Contest 015 解説AtCoder Beginner Contest 015 解説
AtCoder Beginner Contest 015 解説AtCoder Inc.
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Inc.
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話Nagisa Eto
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 

What's hot (20)

明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
最大流 (max flow)
最大流 (max flow)最大流 (max flow)
最大流 (max flow)
 
目指せグラフマスター
目指せグラフマスター目指せグラフマスター
目指せグラフマスター
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
 
図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』図と実装で理解する『木構造入門』
図と実装で理解する『木構造入門』
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
 
双対性
双対性双対性
双対性
 
arc047
arc047arc047
arc047
 
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
AtCoder Beginner Contest 015 解説
AtCoder Beginner Contest 015 解説AtCoder Beginner Contest 015 解説
AtCoder Beginner Contest 015 解説
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説
 
Chokudai search
Chokudai searchChokudai search
Chokudai search
 
Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
Nazoki
NazokiNazoki
Nazoki
 

Viewers also liked

深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶしAtCoder Inc.
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) 智啓 出川
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) 智啓 出川
 
20160620 競技プログラミングのすゝめ
20160620 競技プログラミングのすゝめ20160620 競技プログラミングのすゝめ
20160620 競技プログラミングのすゝめYoshiki TAKADA
 
Rmq
RmqRmq
Rmqoupc
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Inc.
 
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説ACM-ICPC 世界大会 2015 問題 K "Tours" 解説
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説Takuya Akiba
 
競技プログラミング頻出アルゴリズム攻略
競技プログラミング頻出アルゴリズム攻略競技プログラミング頻出アルゴリズム攻略
競技プログラミング頻出アルゴリズム攻略K Moneto
 
大規模グラフ解析のための乱択スケッチ技法
大規模グラフ解析のための乱択スケッチ技法大規模グラフ解析のための乱択スケッチ技法
大規模グラフ解析のための乱択スケッチ技法Takuya Akiba
 
AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説AtCoder Inc.
 
AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説AtCoder Inc.
 
AtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組みAtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組みAtCoder Inc.
 
幾何コンテスト2013
幾何コンテスト2013幾何コンテスト2013
幾何コンテスト2013Naoto Mizuno
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)AtCoder Inc.
 
LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~Yuma Inoue
 
Learning Convolutional Neural Networks for Graphs
Learning Convolutional Neural Networks for GraphsLearning Convolutional Neural Networks for Graphs
Learning Convolutional Neural Networks for GraphsTakuya Akiba
 

Viewers also liked (18)

深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし深さ優先探索による塗りつぶし
深さ優先探索による塗りつぶし
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
 
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS) GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
GPGPU Seminar (GPU Accelerated Libraries, 1 of 3, cuBLAS)
 
20160620 競技プログラミングのすゝめ
20160620 競技プログラミングのすゝめ20160620 競技プログラミングのすゝめ
20160620 競技プログラミングのすゝめ
 
Rmq
RmqRmq
Rmq
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説
 
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説ACM-ICPC 世界大会 2015 問題 K "Tours" 解説
ACM-ICPC 世界大会 2015 問題 K "Tours" 解説
 
競技プログラミング頻出アルゴリズム攻略
競技プログラミング頻出アルゴリズム攻略競技プログラミング頻出アルゴリズム攻略
競技プログラミング頻出アルゴリズム攻略
 
大規模グラフ解析のための乱択スケッチ技法
大規模グラフ解析のための乱択スケッチ技法大規模グラフ解析のための乱択スケッチ技法
大規模グラフ解析のための乱択スケッチ技法
 
素集合データ構造
素集合データ構造素集合データ構造
素集合データ構造
 
AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説AtCoder Regular Contest 049 解説
AtCoder Regular Contest 049 解説
 
AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説AtCoder Beginner Contest 034 解説
AtCoder Beginner Contest 034 解説
 
AtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組みAtCoderに毎回参加したくなる仕組み
AtCoderに毎回参加したくなる仕組み
 
幾何コンテスト2013
幾何コンテスト2013幾何コンテスト2013
幾何コンテスト2013
 
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第五回講義資料(ワークスアプリケーションズ & AtCoder)
 
TCO2017R1
TCO2017R1TCO2017R1
TCO2017R1
 
LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~
 
Learning Convolutional Neural Networks for Graphs
Learning Convolutional Neural Networks for GraphsLearning Convolutional Neural Networks for Graphs
Learning Convolutional Neural Networks for Graphs
 

Similar to プログラミングコンテストでのデータ構造

PFDS 5.5 Pairing heap
PFDS 5.5 Pairing heapPFDS 5.5 Pairing heap
PFDS 5.5 Pairing heap昌平 村山
 
Ibisml2011 06-20
Ibisml2011 06-20Ibisml2011 06-20
Ibisml2011 06-20Yasuo Tabei
 
データを工夫して記録するデータ構造
データを工夫して記録するデータ構造データを工夫して記録するデータ構造
データを工夫して記録するデータ構造Katsutoshi Nagaoka
 
劣モジュラ最適化と機械学習 2.4節
劣モジュラ最適化と機械学習 2.4節劣モジュラ最適化と機械学習 2.4節
劣モジュラ最適化と機械学習 2.4節Hakky St
 
Ordered neurons integrating tree structures into recurrent neural networks
Ordered neurons integrating tree structures into recurrent neural networksOrdered neurons integrating tree structures into recurrent neural networks
Ordered neurons integrating tree structures into recurrent neural networksKazuki Fujikawa
 
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)(文献紹介)Deep Unrolling: Learned ISTA (LISTA)
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)Morpho, Inc.
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門Kimikazu Kato
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説AtCoder Inc.
 
LCCC2010:Learning on Cores, Clusters and Cloudsの解説
LCCC2010:Learning on Cores,  Clusters and Cloudsの解説LCCC2010:Learning on Cores,  Clusters and Cloudsの解説
LCCC2010:Learning on Cores, Clusters and Cloudsの解説Preferred Networks
 
キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達Kumazaki Hiroki
 
はじめてのパターン認識 第11章 11.1-11.2
はじめてのパターン認識 第11章 11.1-11.2はじめてのパターン認識 第11章 11.1-11.2
はじめてのパターン認識 第11章 11.1-11.2Prunus 1350
 

Similar to プログラミングコンテストでのデータ構造 (20)

PFDS 5.5 Pairing heap
PFDS 5.5 Pairing heapPFDS 5.5 Pairing heap
PFDS 5.5 Pairing heap
 
凸包
凸包凸包
凸包
 
Ibisml2011 06-20
Ibisml2011 06-20Ibisml2011 06-20
Ibisml2011 06-20
 
WUPC2012
WUPC2012WUPC2012
WUPC2012
 
データを工夫して記録するデータ構造
データを工夫して記録するデータ構造データを工夫して記録するデータ構造
データを工夫して記録するデータ構造
 
劣モジュラ最適化と機械学習 2.4節
劣モジュラ最適化と機械学習 2.4節劣モジュラ最適化と機械学習 2.4節
劣モジュラ最適化と機械学習 2.4節
 
Ordered neurons integrating tree structures into recurrent neural networks
Ordered neurons integrating tree structures into recurrent neural networksOrdered neurons integrating tree structures into recurrent neural networks
Ordered neurons integrating tree structures into recurrent neural networks
 
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)(文献紹介)Deep Unrolling: Learned ISTA (LISTA)
(文献紹介)Deep Unrolling: Learned ISTA (LISTA)
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
210122 msi dp
210122 msi dp210122 msi dp
210122 msi dp
 
CVIM mean shift-3
CVIM mean shift-3CVIM mean shift-3
CVIM mean shift-3
 
PFI Christmas seminar 2009
PFI Christmas seminar 2009PFI Christmas seminar 2009
PFI Christmas seminar 2009
 
Random Forests
Random ForestsRandom Forests
Random Forests
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説
 
LCCC2010:Learning on Cores, Clusters and Cloudsの解説
LCCC2010:Learning on Cores,  Clusters and Cloudsの解説LCCC2010:Learning on Cores,  Clusters and Cloudsの解説
LCCC2010:Learning on Cores, Clusters and Cloudsの解説
 
データ処理
データ処理データ処理
データ処理
 
M1 gp_Disco
M1 gp_DiscoM1 gp_Disco
M1 gp_Disco
 
キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達
 
はじめてのパターン認識 第11章 11.1-11.2
はじめてのパターン認識 第11章 11.1-11.2はじめてのパターン認識 第11章 11.1-11.2
はじめてのパターン認識 第11章 11.1-11.2
 

More from Takuya Akiba

分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17Takuya Akiba
 
TCO15 Algorithm Round 2C 解説
TCO15 Algorithm Round 2C 解説TCO15 Algorithm Round 2C 解説
TCO15 Algorithm Round 2C 解説Takuya Akiba
 
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-Takuya Akiba
 
Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Takuya Akiba
 
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズムTakuya Akiba
 
大規模ネットワークの性質と先端グラフアルゴリズム
大規模ネットワークの性質と先端グラフアルゴリズム大規模ネットワークの性質と先端グラフアルゴリズム
大規模ネットワークの性質と先端グラフアルゴリズムTakuya Akiba
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
 
大規模グラフアルゴリズムの最先端
大規模グラフアルゴリズムの最先端大規模グラフアルゴリズムの最先端
大規模グラフアルゴリズムの最先端Takuya Akiba
 

More from Takuya Akiba (8)

分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17分散深層学習 @ NIPS'17
分散深層学習 @ NIPS'17
 
TCO15 Algorithm Round 2C 解説
TCO15 Algorithm Round 2C 解説TCO15 Algorithm Round 2C 解説
TCO15 Algorithm Round 2C 解説
 
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
乱択データ構造の最新事情 -MinHash と HyperLogLog の最近の進歩-
 
Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5Cache-Oblivious データ構造入門 @DSIRNLP#5
Cache-Oblivious データ構造入門 @DSIRNLP#5
 
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
 
大規模ネットワークの性質と先端グラフアルゴリズム
大規模ネットワークの性質と先端グラフアルゴリズム大規模ネットワークの性質と先端グラフアルゴリズム
大規模ネットワークの性質と先端グラフアルゴリズム
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 
大規模グラフアルゴリズムの最先端
大規模グラフアルゴリズムの最先端大規模グラフアルゴリズムの最先端
大規模グラフアルゴリズムの最先端
 

プログラミングコンテストでのデータ構造