Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
区間と平方分割と私
Search
Kashee337
June 27, 2023
45
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
区間と平方分割と私
社内勉強会資料
Kashee337
June 27, 2023
More Decks by Kashee337
See All by Kashee337
DeepTechで社会課題を解決する上で直面した課題
kashihara
0
86
多様なニーズに対応可能なGPS基盤にするために考えたこと
kashihara
0
170
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
BBQ
matthewcrist
89
10k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
Code Review Best Practice
trishagee
74
20k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
970
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
350
Unsuck your backbone
ammeep
672
58k
Code Reviewing Like a Champion
maltzj
528
40k
Everyday Curiosity
cassininazir
0
340
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Transcript
区間と平方分割と私 Ryota Kashihara 1
初めに 平方分割とは n個の要素を持つ列を の要素にバケットにまとめて管理する手法の俗称 〜蟻本より〜 何ができるのか 例えばRMQで取り扱うような区間に対する処理を で処理でき、SegmentTreeと同様 にデータの持たせ方次第で様々な機能を実装できる。
n O( ) n 2
RMQを解く N個の要素を持つ数列に対して以下の2種類のクエリが 個与えられ処理することを考える。 find(l,r):区間 における要素の最小値を出力する update(i,v): 番目の要素を へ更新する 愚直に解くと、最悪ケースで かかってしまう。SegmentTreeで
で解け る問題として典型的な問題。今回は平方分割で で解く。 ※ ここでは一点更新型のRMQを前提としている。補助データ構造を使えば区間更新へも対応 できるが今回は割愛。 Q [l, r) i v O(NQ) O(QlogN) O(Q ) n 3
平方分割によるRMQ RMQを解く場合は以下のように要素が9個の場合を考えて3個ずつの要素をバケットへまとめ バケット毎に最小値を計算しておく。 ある区間クエリ が与えられた時、区間は2つのケースに分割される。図の①③はバケッ トと区間に重なりはあるが完全に含まれていない。対して②は区間 に完全に含まれてい る。この時、各々以下のように最小値を探索すれば で処理可能。値の更新も、同じ バケット内の要素
だけ見れば良いので で実現できる。 ①③:愚直に探索 => 高々 ②:バケットの最小値 => [l, r) [l, r) O( ) n n O( ) n O( ) n O(1) 4
実装(1/3) バケットの初期化 で量子化したバケット単位で最小値を計算しておく。 vector<int> a; int n, b; vector<int> bucket;
SQDC(vector<int>& _a) : a(_a) { n = _a.size(); b = sqrt(n); bucket.assign(int(n / b), MAX); for (int i = 0; i < n; i++) { bucket[i / b] = min(a[i], bucket[i / b]); } } n 5
実装(2/3) find int find(int l, int r) { int tl
= max(0, l); int tr = min(n - 1, r); int ans = MAX; // 左から探す while (tl < tr && tl % b != 0) ans = min(a[tl++], ans); // 右から探す while (tl < tr && (tr + 1) % b != 0) ans = min(a[tr--], ans); // bucket 単位で探す while (tl < tr) { int bi = tl / b; ans = min(ans, bucket[bi]); tl += b; } return ans; } 6
実装(3/3) update void update(int j, int v) { if (j
< 0 || j >= n) return; int bj = j / b; a[j] = v; // bucket の最小値を更新 bucket[bj] = MAX; for (int i = b * bj; i < b * (bj + 1); i++) { bucket[i / b] = min(a[i], bucket[i / b]); } } 7
蟻本に乗ってる問題 POJ2104 K-th Number 整数値の数列 が与えられる。m個のクエリが与えられ、各クエリ に対して、部分列 を昇順にソートした時の 番目の要素を出 力せよ。
制約 , SegmentTreeでも解けるが平方分割の方が実装がシンプルになる。 a , a , ..., a 1 2 n Q(i, j, k) a , a , ..., a i i+1 j k 1 ≤ n ≤ 100000 1 ≤ m ≤ 5000 8
平方分割とSegmentTree 区間に対する平方分割の応用ではSegmentTreeでも同様の機能を実装できるケースが多く、 動作も早い。ただし、平方分割の方が実装がシンプルになるケースも多いため、覚えておい てSegmentTreeでの実装が思いつかないケースなどに適用してみると良いかもしれない。 ※ 典型90-83:ColorfulGraphなどはSegmentTreeで書くの難しそう。そもそも書けるのだろう か。 9
おまけ 話は変わって、findクエリの返り値として区間に存在する要素の種類数を返す必要のある場合 どうすれば良いだろうか。この場合、バケット内の要素で何が何個あったかという情報まで が必要になるためRMQと同じようなやり方でバケット毎に種類数を集約する方法では取り扱 うことはできない。このような問題に対して適用できる平方分割の応用としてMo's Algorithmという手法がある。 10
Mo's Algorythm 俗称クエリ平方分割と呼ばれるアルゴリズム。 区間に対するクエリをオフラインでまとめてバケット単位で処理することで高速化。 以下の条件を満たせば適用できる可能性がある。 要素の更新無し オフライン処理 区間 から の結果が高速に計算できる
※ 細かい説明を書こうかとも思ったがこのブログが分かり易すぎるので貼って見るスタイルで (https://ei1333.hateblo.jp/entry/2017/09/11/211011) [l, r) [l + 1, r), [l − 1, r), [l, r + 1), [l, r − 1) 11
参考 https://book.mynavi.jp/ec/products/detail/id=22672 蟻本 https://kujira16.hateblo.jp/entry/2016/12/15/000000#fn-89e8aedb 区間更新型などタイプ別に詳しい図入りで解説されていてかなり分かりやすい https://snuke.hatenablog.com/entry/2016/07/01/000000 永続データ構造を使ったMo'sの上位互換の話もある(理解してません)。 12