Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
みんなで書こう二分探索
Search
matumoto
June 10, 2021
Technology
72
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
みんなで書こう二分探索
2021/7月の大LTでの発表資料です
イベントページはこちら
https://zli.connpass.com/event/216615/
matumoto
June 10, 2021
More Decks by matumoto
See All by matumoto
Go標準パッケージのI/O処理をながめる
matumoto
0
440
testingを眺める
matumoto
1
220
sync/v2 プロポーザルの 背景と sync.Pool について
matumoto
0
790
Goトランザクション処理
matumoto
1
87
いまいちどスライスの 挙動を見直してみる
matumoto
0
420
Go1.22のリリース予定の機能を見る
matumoto
0
90
GoのUnderlying typeについて
matumoto
0
240
Typed-nilについて
matumoto
0
380
GoのType Setsという概念
matumoto
0
62
Other Decks in Technology
See All in Technology
トヨタ⽣産⽅式(TPS)⼊⾨
recruitengineers
PRO
3
720
【CEDEC2026】『GRANBLUE FANTASY: Relink - Endless Ragnarok』のバトル制作事例 ~最高のキャラゲーを目指して~
cygames
PRO
0
250
認知負荷をGemini で溶かす — GKE 基盤「Orbit」における AI エージェントの実践
sansantech
PRO
1
290
サイバー捜査員研修(後半)
nomizone
1
850
【CEDEC2026】ゲームシナリオライターを支援するAIツール開発の実践 ― 設計とプロンプトの工夫 ―
cygames
PRO
1
790
Forza Horizon 6 のテレメトリ機能で 自動運転に使えそうな学習データを集める話
henjin0
0
160
取引先から届く 「セキュリティチェックシート」の読み解き方
kamadamakoto
0
140
今こそ聞きたいソフトウェア設計 ドメイン駆動設計再入門
masuda220
PRO
17
7.1k
事業価値と Engineering 2026年度版
recruitengineers
PRO
49
23k
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
19k
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
210
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
720
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
270
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Designing for Timeless Needs
cassininazir
1
440
Everyday Curiosity
cassininazir
0
270
Code Review Best Practice
trishagee
74
20k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Discover your Explorer Soul
emna__ayadi
2
1.3k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
460
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Transcript
みんなで書こう二分探索 会津大学2年松本響輝
二分探索って? ・二分していく探索です それ以上でもそれ以下でもない 探索する区間の長さをNとして なんと計算量オーダーがO(logN)ではやい! 半分,半分,半分,半分,......................
強い方のツイートで一時期盛り上がりました
どういう動き方か
どう動くの? 端っこを決めて、その真ん中で区間を分けていく。 使う方 使う方 使う方
なにを求められるのか
なにができるの ・ある境界を求められる 例 A = {3, 5, 10, 20, 33,
90, 98}の配列で値が15以上を満たす最小の index を返す場合 left : 0 right : 6 mid : 3 ← ( left + right ) / 2 A mid は20なので、15以上! ということは、探索する区間を左側にずらす→ right を mid にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 0 right : 3 ← mid mid : 1 ← ( left + right ) / 2 A mid は5なので、15以上じゃない! ということは、探索する区間を右側にずらす→ left を mid + 1にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 2 ← mid + 1 right : 3 mid : 2 ← ( left + right ) / 2 A mid は10なので、15以上! ということは、探索する区間を右側にずらす→ left を mid + 1にする
A = {3, 5, 10, 20, 33, 90, 98}の配列で値が15以上を満たす最小の index
を返す場合 left : 3 ← mid + 1 right : 3 mid : 3 ← ( left + right ) / 2 A mid は20なので、15以上! left と right が同じになったので left を返す( right でもよい)
なにを求めるの? ・ある境界を求められる つまり、条件を定めたときの境界を求めることができる ・ソート済みの配列の中で値が10以上を満たす最小の index ・0~n以下の素数の中で200000以上の最小の素数 条件が有効でない部分 条件が有効な部分 ※境界は整数でないこともあります
なにがうれしいのか
なにがうれしい? ・応用ができる! 例:値の検索 配列の中で値が x 以上を満たす最小の index → index 番目が
x ならOK、そうでないならその配列にはない ・計算量が少ない! 最悪でも計算量がO(logN) 0~1018くらいの区間だったとしても十分に高速(そんな大きい数を扱う職場...)
None
実装は? 1. 二分探索を使わない 2. 標準の関数を使う 3. 自分で作る
1.二分探索を使わない
1.二分探索を使わない (´・ω・`) え?
2.標準の関数を使う
2.標準の関数を使う • C++ ◦ lower_bound ◦ upper_bound • Python ◦
bisect • java ◦ Arrays.binarySearch ただ、配列に対して二分探索はできるが それ以外への二分探索ができない...
3.自分で作る
3.自分で作る(C++) 関数にするより、テンプレを覚えて書いた方が汎用性がよい! そんなあなたにめぐる式二分探索! ※競技プログラミング界隈はキャラがおおいがち 因幡めぐるアカウント様( https://twitter.com/meguru_comp)より
めぐる式二分探索の前に.. ・二分探索の実装上の工夫(先人たちの汗と涙の知恵) • 区間は半開区間[ left, right )で扱う 閉区間[ left, right
] これは left 以上 right 以下 半開区間 [ left, right ) これは left 以上 right 未満 今まで [ left, right ] → [ left, mid - 1 ]だったが [ left, right ) → [ left, mid )と簡潔に! ※ left を mid にする場合もおなじ ついでに、長さが N の配列のとき [ 0, N - 1 ] としてたのが [ 0, N ) にできる
めぐる式二分探索とは • めぐる式二分探索の特徴 ・ループの条件に絶対値を使っている ・ok, ng などの変数がある ・半開区間 ・最終的には ok
に求めたい値が入っている ・判定部分を関数にしている(←これについては諸説ありです) (ok, ng 以外の変数名の候補としては valid, invalid がある)
valid, invalid(ok, ng)みたいな変数には何の値が入るの? • ある条件を元にその境界を求めたい→二分探索でのis_valid関数を作る • validにはis_valid(valid)としたときに必ずtrueとなる値を入れる • invalidにはis_valid(invalid)としたときに必ずfalseとなる値を入れる •
例 ◦ n要素のソート済み配列 aからx以上の要素の最小のインデックスを見つけたい ▪ (配列aにはx以上の要素が少なくとも 1つは存在するものとする ) ◦ is_valid関数はindexを受け取ってa[i] >= x かどうかを判定するように作る ◦ validの初期値にはn-1を入れておく ◦ invalidの初期値には-1を入れておく(今回は invalidが開区間なので0じゃない) ◦ これであとは二分探索するだけ ▪ ※実際には、配列aの末尾に番兵として INFを挿入してvalid=nとする方が多いと思います
閉区間の実装と比較 ・+1, -1 を考えるのが混乱させる ・left か right のどちらにほしい値があるのか考える必要がある
閉区間の実装と比較 ・is_valid 関数を作ると、条件だけ考えることができる ・最終的にほしい値が valid だと分かりやすい ←の is_valid 関数は C++
のラムダ式です
これであなたも快適な二分探索ライフを! ご清聴ありがとうございました