Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
みんなで書こう二分探索
Search
matumoto
June 10, 2021
Technology
0
68
みんなで書こう二分探索
2021/7月の大LTでの発表資料です
イベントページはこちら
https://zli.connpass.com/event/216615/
matumoto
June 10, 2021
Tweet
Share
More Decks by matumoto
See All by matumoto
testingを眺める
matumoto
1
170
sync/v2 プロポーザルの 背景と sync.Pool について
matumoto
0
550
Goトランザクション処理
matumoto
1
56
いまいちどスライスの 挙動を見直してみる
matumoto
0
360
Go1.22のリリース予定の機能を見る
matumoto
0
70
GoのUnderlying typeについて
matumoto
0
210
Typed-nilについて
matumoto
0
350
GoのType Setsという概念
matumoto
0
33
GoのRateLimit処理の実装
matumoto
0
430
Other Decks in Technology
See All in Technology
たまに起きる外部サービスの障害に備えたり備えなかったりする話
egmc
0
390
ソフトウェアエンジニアとAIエンジニアの役割分担についてのある事例
kworkdev
PRO
0
150
シニアソフトウェアエンジニアになるためには
kworkdev
PRO
3
260
re:Invent2025 3つの Frontier Agents を紹介 / introducing-3-frontier-agents
tomoki10
0
400
mairuでつくるクレデンシャルレス開発環境 / Credential-less development environment using Mailru
mirakui
5
590
Strands Agents × インタリーブ思考 で変わるAIエージェント設計 / Strands Agents x Interleaved Thinking AI Agents
takanorig
4
1.8k
TED_modeki_共創ラボ_20251203.pdf
iotcomjpadmin
0
130
MySQLとPostgreSQLのコレーション / Collation of MySQL and PostgreSQL
tmtms
1
1.1k
[2025-12-12]あの日僕が見た胡蝶の夢 〜人の夢は終わらねェ AIによるパフォーマンスチューニングのすゝめ〜
tosite
0
140
AWSの新機能をフル活用した「re:Inventエージェント」開発秘話
minorun365
2
400
まだ間に合う! Agentic AI on AWSの現在地をやさしく一挙おさらい
minorun365
17
2.4k
「図面」から「法則」へ 〜メタ視点で読み解く現代のソフトウェアアーキテクチャ〜
scova0731
0
480
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
86
Building the Perfect Custom Keyboard
takai
1
660
Context Engineering - Making Every Token Count
addyosmani
9
540
Designing for Timeless Needs
cassininazir
0
92
Design in an AI World
tapps
0
97
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
57
37k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.8k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.2k
Agile that works and the tools we love
rasmusluckow
331
21k
A Tale of Four Properties
chriscoyier
162
23k
エンジニアに許された特別な時間の終わり
watany
105
220k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
79
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++
のラムダ式です
これであなたも快適な二分探索ライフを! ご清聴ありがとうございました