Soumettre la recherche
Mettre en ligne
色々なダイクストラ高速化
•
41 j'aime
•
25,282 vues
Y
yosupo
Suivre
色々なダイクストラ高速化とありますが結局はRadixHeapの解説です
Lire moins
Lire la suite
Technologie
Signaler
Partager
Signaler
Partager
1 sur 35
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
指数時間アルゴリズム入門
指数時間アルゴリズム入門
Yoichi Iwata
双対性
双対性
Yoichi Iwata
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
Takuya Akiba
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
Takuya Akiba
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
Takuya Akiba
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
Takuya Akiba
Rolling Hashを殺す話
Rolling Hashを殺す話
Nagisa Eto
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
shindannin
Recommandé
指数時間アルゴリズム入門
指数時間アルゴリズム入門
Yoichi Iwata
双対性
双対性
Yoichi Iwata
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
Takuya Akiba
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
Takuya Akiba
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
Takuya Akiba
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
Takuya Akiba
Rolling Hashを殺す話
Rolling Hashを殺す話
Nagisa Eto
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
shindannin
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
Takuya Akiba
直交領域探索
直交領域探索
okuraofvegetable
Rolling hash
Rolling hash
HCPC: 北海道大学競技プログラミングサークル
様々な全域木問題
様々な全域木問題
tmaehara
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
Kensuke Otsuki
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
HCPC: 北海道大学競技プログラミングサークル
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
Takuya Akiba
Union find(素集合データ構造)
Union find(素集合データ構造)
AtCoder Inc.
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
最大流 (max flow)
最大流 (max flow)
HCPC: 北海道大学競技プログラミングサークル
全域木いろいろ
全域木いろいろ
HCPC: 北海道大学競技プログラミングサークル
abc032
abc032
AtCoder Inc.
Convex Hull Trick
Convex Hull Trick
HCPC: 北海道大学競技プログラミングサークル
グラフと木
グラフと木
京大 マイコンクラブ
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
Hibiki Yamashiro
充足可能性問題のいろいろ
充足可能性問題のいろいろ
Hiroshi Yamashita
一般グラフの最大マッチング
一般グラフの最大マッチング
HCPC: 北海道大学競技プログラミングサークル
Binary indexed tree
Binary indexed tree
HCPC: 北海道大学競技プログラミングサークル
Chokudai search
Chokudai search
AtCoder Inc.
目指せグラフマスター
目指せグラフマスター
HCPC: 北海道大学競技プログラミングサークル
WUPC2012
WUPC2012
Dai Hamada
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
Contenu connexe
Tendances
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
Takuya Akiba
直交領域探索
直交領域探索
okuraofvegetable
Rolling hash
Rolling hash
HCPC: 北海道大学競技プログラミングサークル
様々な全域木問題
様々な全域木問題
tmaehara
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
Kensuke Otsuki
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
HCPC: 北海道大学競技プログラミングサークル
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
Takuya Akiba
Union find(素集合データ構造)
Union find(素集合データ構造)
AtCoder Inc.
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
最大流 (max flow)
最大流 (max flow)
HCPC: 北海道大学競技プログラミングサークル
全域木いろいろ
全域木いろいろ
HCPC: 北海道大学競技プログラミングサークル
abc032
abc032
AtCoder Inc.
Convex Hull Trick
Convex Hull Trick
HCPC: 北海道大学競技プログラミングサークル
グラフと木
グラフと木
京大 マイコンクラブ
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
Hibiki Yamashiro
充足可能性問題のいろいろ
充足可能性問題のいろいろ
Hiroshi Yamashita
一般グラフの最大マッチング
一般グラフの最大マッチング
HCPC: 北海道大学競技プログラミングサークル
Binary indexed tree
Binary indexed tree
HCPC: 北海道大学競技プログラミングサークル
Chokudai search
Chokudai search
AtCoder Inc.
目指せグラフマスター
目指せグラフマスター
HCPC: 北海道大学競技プログラミングサークル
Tendances
(20)
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
直交領域探索
直交領域探索
Rolling hash
Rolling hash
様々な全域木問題
様々な全域木問題
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
二部グラフの最小点被覆と最大安定集合と最小辺被覆の求め方
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
Union find(素集合データ構造)
Union find(素集合データ構造)
明日使えないすごいビット演算
明日使えないすごいビット演算
最大流 (max flow)
最大流 (max flow)
全域木いろいろ
全域木いろいろ
abc032
abc032
Convex Hull Trick
Convex Hull Trick
グラフと木
グラフと木
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
充足可能性問題のいろいろ
充足可能性問題のいろいろ
一般グラフの最大マッチング
一般グラフの最大マッチング
Binary indexed tree
Binary indexed tree
Chokudai search
Chokudai search
目指せグラフマスター
目指せグラフマスター
Similaire à 色々なダイクストラ高速化
WUPC2012
WUPC2012
Dai Hamada
冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
Hisatoshi Onishi
Jpoug 20120721
Jpoug 20120721
Koji Shinkubo
SVM -R-
SVM -R-
Yuu Kimy
Material
Material
_TUNE_
Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)
Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)
mametter
虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表Ver
Kensuke Otsuki
マルチコアを用いた画像処理
マルチコアを用いた画像処理
Norishige Fukushima
USP友の会勉強会、状態遷移図の巻
USP友の会勉強会、状態遷移図の巻
Ryuichi Ueda
HPC Phys-20201203
HPC Phys-20201203
MITSUNARI Shigeo
“Stay Right”ペンテスト体験:SANS Holiday Hack Challenge 2017の解説 & Walkthrough
“Stay Right”ペンテスト体験:SANS Holiday Hack Challenge 2017の解説 & Walkthrough
Isaac Mathis
ICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったか
ina job
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
㉑CSSでアニメーション!その2
㉑CSSでアニメーション!その2
Nishida Kansuke
Arduinoでプログラミングに触れてみよう 続編
Arduinoでプログラミングに触れてみよう 続編
Hiromu Yakura
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
Kimikazu Kato
Gorinphp0729
Gorinphp0729
akitsukada
Gorinphp0729
Gorinphp0729
akitsukada
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
AtCoder Inc.
Similaire à 色々なダイクストラ高速化
(20)
WUPC2012
WUPC2012
冬のLock free祭り safe
冬のLock free祭り safe
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
Jpoug 20120721
Jpoug 20120721
SVM -R-
SVM -R-
Material
Material
Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)
Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)
虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表Ver
マルチコアを用いた画像処理
マルチコアを用いた画像処理
USP友の会勉強会、状態遷移図の巻
USP友の会勉強会、状態遷移図の巻
HPC Phys-20201203
HPC Phys-20201203
“Stay Right”ペンテスト体験:SANS Holiday Hack Challenge 2017の解説 & Walkthrough
“Stay Right”ペンテスト体験:SANS Holiday Hack Challenge 2017の解説 & Walkthrough
ICFP2009-いかにして我々は戦ったか
ICFP2009-いかにして我々は戦ったか
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
㉑CSSでアニメーション!その2
㉑CSSでアニメーション!その2
Arduinoでプログラミングに触れてみよう 続編
Arduinoでプログラミングに触れてみよう 続編
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
Gorinphp0729
Gorinphp0729
Gorinphp0729
Gorinphp0729
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
Dernier
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
Toru Tamaki
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
iPride Co., Ltd.
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
Toru Tamaki
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
Ryo Sasaki
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
sugiuralab
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
Toru Tamaki
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
taisei2219
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Yuma Ohgami
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
danielhu54
Dernier
(9)
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
色々なダイクストラ高速化
1.
ダイクストラ法高速化いろいろ @yosupot
2.
ダイクストラ法とは • 単一始点最短経路を求める有名なアルゴリズム • 普通のヒープを使って計算量はO((V+E)logV) •
O(V^2)もありますが今回は触れません
3.
ダイクストラを高速化したい!
4.
ダイクストラが遅くて困る時の原因
5.
ダイクストラが遅くて困る時の原因 1. 解法が間違っている
6.
ダイクストラが遅くて困る時の原因 1. 解法が間違っている 2. 他の部分が遅い
7.
ダイクストラが遅くて困る時の原因 1. 解法が間違っている 2. 他の部分が遅い 3.
ジャッジがPKU
8.
ダイクストラは速い!!! 甘えるな!!!!
9.
ご静聴 ありがとうございました 参考:http://www.slideshare.net/qnighy/ss-15312828
10.
でも本当に高速化はいらない? • 最小費用流とかも速くなる • めちゃ定数倍が厳しいのがあったら役に立つかも •
そもそも速度は速いに越したことはない
11.
高速化(基本編)
12.
1 const int
V = 10000, INF = 1<<28; 2 using P = pair<int, int>; 3 vector<P> G[V]; // pair<辺の距離, 行き先の頂点> 4 T dist[V]; // dist[i]はsから頂点iへの最短距離が入る 5 bool used[V]; 6 void dijkstra(int s) { // s:始点 7 fill_n(dist, V, INF); 8 fill_n(used, V, false); 9 priority_queue<P, vector<P>, greater<P>> q; 10 q.push(P(0, s)); 11 while (!q.empty()) { 12 T d; int t;//d:sからの距離 t:行き先 13 tie(d, t) = q.top(); q.pop(); 14 if (used[t]) continue; //もう既に探索済みか 15 used[t] = true; dist[t] = d; 16 for (P e: G[t]) { 17 18 q.push(P(d+e.first, e.second)); 19 } 20 } 21 } 普通のDijkstra
13.
1 const int
V = 10000, INF = 1<<28; 2 using P = pair<int, int>; 3 vector<P> G[V]; // pair<辺の距離, 行き先の頂点> 4 T dist[V]; // dist[i]はsから頂点iへの最短距離が入る 5 bool used[V]; 6 void dijkstra(int s) { // s:始点 7 fill_n(dist, V, INF); 8 fill_n(used, V, false); 9 priority_queue<P, vector<P>, greater<P>> q; 10 q.push(P(0, s)); 11 while (!q.empty()) { 12 T d; int t;//d:sからの距離 t:行き先 13 tie(d, t) = q.top(); q.pop(); 14 if (used[t]) continue; //もう既に探索済みか 15 used[t] = true; dist[t] = d; 16 for (P e: G[t]) { 17 18 q.push(P(d+e.first, e.second)); 19 } 20 } 21 } 普通のDijkstra ここに
14.
1 const int
V = 10000, INF = 1<<28; 2 using P = pair<int, int>; 3 vector<P> G[V]; // pair<辺の距離, 行き先の頂点> 4 T dist[V]; // dist[i]はsから頂点iへの最短距離が入る 5 bool used[V]; 6 void dijkstra(int s) { // s:始点 7 fill_n(dist, V, INF); 8 fill_n(used, V, false); 9 priority_queue<P, vector<P>, greater<P>> q; 10 q.push(P(0, s)); 11 while (!q.empty()) { 12 T d; int t;//d:sからの距離 t:行き先 13 tie(d, t) = q.top(); q.pop(); 14 if (used[t]) continue; //もう既に探索済みか 15 used[t] = true; dist[t] = d; 16 for (P e: G[t]) { 17 18 q.push(P(d+e.first, e.second)); 19 } 20 } 21 } 普通のDijkstra if (dist[e.second] <= d+e.first) continue; こう
15.
高速化(基本編) • 単純な枝狩り 非常に有名 •
priority_queueに入れる前にその時点での最短距離をチェック • めちゃ効果が高い これを行うと何十倍も速くなる問題も
16.
高速化(基本編) • 単純な枝狩り 非常に有名 •
priority_queueに入れる前にその時点での最短距離をチェック • めちゃ効果が高い これを行うと何十倍も速くなる問題も http://abc012.contest.atcoder.jp/tasks/abc012_4 ABC12D 避けられない運命 UTPC2013L 1円ロード http://utpc2013.contest.atcoder.jp/tasks/utpc2013_12 この枝刈りを使わないと厳しい問題もある (そもそもこれはO((V+E)logV)ダイクストラは想定解ではない)
17.
ここからは、いくつか特殊なケースでの 高速化を紹介します
18.
辺の長さが小数(doubleとか)の場合
19.
辺の長さが小数(doubleとか)の場合 このスライドはここで(本当に)終了です。 ご静聴ありがとうございました
20.
辺の長さが整数 • 辺の長さが 1
のみ → BFSをしろ • 辺の長さが 0 or 1 のみ → 0-1BFSをしろ • 辺の長さが100以下とか→キューを101個用意しろ
21.
• 辺の長さが大きい場合 • RadixHeapという高速なHeapがあります •
このスライドの本題です 辺の長さが整数
22.
RadixHeapとは • 非負整数専用Heap • 最後に取り出した値より小さな値を入れられない •
計算量はならしO(logD) (D: 入れたい値の最大値) • 定数倍がめちゃ軽い • 64bit版も出来ますが, 今回は32bitで説明します
23.
1 int bsr(uint
x) { 2 if (x == 0) return -1; 3 return 31-__builtin_clz(x); 4 } 5 6 struct RadixHeapInt { 7 vector<uint> v[33]; 8 uint last, sz; 9 RadixHeapInt() { 10 last = sz = 0; 11 } 12 void push(uint x) { 13 assert(last <= x); 14 sz++; 15 v[bsr(x^last)+1].push_back(x); 16 } 17 uint pop() { 18 assert(sz); 19 if (!v[0].size()) { 20 int i = 1; 21 while (!v[i].size()) i++; 22 uint new_last = 23 *min_element(v[i].begin(), v[i].end()); 24 for (uint x: v[i]) { 25 v[bsr(x^new_last)+1].push_back(x); 26 } 27 last = new_last; 28 v[i].clear(); 29 } 30 sz--; 31 v[0].pop_back(); 32 return last; 33 } 34 }; ソースコード 実装は重くない (skew heapよりは重い)
24.
• Bit Search
Reverseの略 • 一番左の1のbitが(0-indexedで)何番目かを数える • ロバストなlog2(x)とも考えられる • __builtin_clz(x)は31-bsr(x)を返してくれる便利関数 1 int bsr(uint x) { 2 if (x == 0) return -1; 3 return 31-__builtin_clz(x); 4 } bsrとは? • 0b00010000 -> 4 • 0b01011001 -> 6 • 0b11111111 -> 0 • 0b00000000 -> -1 (builtin_clzに0を渡すとぶっ壊れるため場合分け)
25.
push 1 void push(uint
x) { 2 assert(last <= x); 3 sz++; 4 v[bsr(x^last)+1].push_back(x); 5 } • RadixHeapでは値がpushされるとbsr(x^last)+1によって33 個のバッファに振り分けられる • 逆にd個目のバッファの中の値xについてd==bsr(x^last)+1 というのはいつでも(pushした後もpopした後も)33個の バッファの中の全ての値について成立していなければいけな い • push関数自体はv[bsr(x^last)+1]に値を放り込むだけでいい
26.
push v[i] 中身(last=12) 0 0b00001100 1
0b00001101 2 0b0000111x 3 該当なし 4 該当なし 5 0b0001xxxx 6 0b001xxxxx 7 0b01xxxxxx 8 0b1xxxxxxx 右はlast=12(0b00001100)の時の例 重要な性質 • lastに関わらずlastと同じ値はv[0]に入る • 逆にv[0]にはlastと同じ値しか入れない • v[i+1]の値は必ずv[i]の値より大きい • v[3]とv[4]は12未満の要素しか入れない 1 void push(uint x) { 2 assert(last <= x); 3 sz++; 4 v[bsr(x^last)+1].push_back(x); 5 } →必ず空
27.
pop 1 uint pop()
{ 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 } v[0]に値が入っている場合 v[0]に値が入っていない場合
28.
pop 1 uint pop()
{ 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 } v[0]に値が入っている場合 → 中身は必ずlastと同じ値(つまり最小)なので取り出せばいい v[0]に値が入っていない場合
29.
pop 1 uint pop()
{ 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 } v[0]に値が入っている場合 → 中身は必ずlastと同じ値(つまり最小)なので取り出せばいい v[0]に値が入っていない場合 → v[i+1]の値 v[i]の値であることに注目
30.
pop 1 uint pop()
{ 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 } v[0]に値が入っている場合 → 中身は必ずlastと同じ値(つまり最小)なので取り出せばいい v[0]に値が入っていない場合 → v[i+1]の値 v[i]の値であることに注目 → v[1], v[2], v[3] … と順に中身があるかチェック 中身があったらその中での最小値が全体での最小値
31.
pop 1 uint pop()
{ 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 } v[0]に値が入っている場合 → 中身は必ずlastと同じ値(つまり最小)なので取り出せばいい v[0]に値が入っていない場合 → v[i+1]の値 v[i]の値であることに注目 → v[1], v[2], v[3] … と順に中身があるかチェック 中身があったらその中での最小値が全体での最小値 ただしそのまま取り出すだけではダメ 値の再振り分けが必要
32.
pop 引き続きv[0]に値が入っていない場合を考える v[i]から新しく最小値new_lastを取り出したとする → i, i+1,
i+2 … bit目はlastとnew_lastで変わらない → v[i+1], v[i+2], v[i+3] … に入る値の範囲は変わらない! → bsr(last^new_last) は当然 i-1 更に、v[i]から新しく取り出したならv[0], v[1], … v[i-1]は空 → 結局再振り分けするのはv[i]の中身だけでいい! 1 uint pop() { 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 }
33.
pop そして、v[i]の値とnew_lastはi-1, i, i+1,
… bit目は等しい → 再振り分けされたv[i]の値は必ずv[j](j < i)へ行く (i, i+1, i+2 … bit目はlastとnew_lastで変わらない事とnew_lastはv[i]に属すことから) → 一つの値について、それが再振り分けされる回数は必ず32回以内 → ならし計算量がO(logD)になることが保証される 1 uint pop() { 2 assert(sz); 3 if (!v[0].size()) { 4 int i = 1; 5 while (!v[i].size()) i++; 6 uint new_last = 7 *min_element(v[i].begin(), v[i].end()); 8 for (uint x: v[i]) { 9 v[bsr(x^new_last)+1].push_back(x); 10 } 11 last = new_last; 12 v[i].clear(); 13 } 14 sz--; 15 v[0].pop_back(); 16 return last; 17 }
34.
• unsigned long
long版を作ればpair<int, int>を入れられ るのでダイクストラに使用できます • unsigned int版を改造してもダイクストラに使用できます →こちら(https://github.com/yosupo06/Algorithm/ blob/master/Cpp/Data%20Structure/RadixHeap.h)
35.
まとめ • そもそもダイクストラの高速化が必要になることは ほとんど無い • それでも速度が欲しかったり、最小費用流を高速化 したかったり、高速なHeapが欲しいなら RadixHeapはサイコー
Télécharger maintenant