SlideShare a Scribd company logo
1 of 32
Download to read offline
ICPC勉強会 2015/01/08
RMQ クエリ処理
北海道大学大学院 情報科学研究科
博士1年 井上 祐馬
1
ICPC勉強会 2015/01/08
• RMQ: Range Minimum Query (区間最小値)
• 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r)
• A[l:r] 中での最小値 A[i] を返す
• 基本的に最大値クエリも同様に処理できる
RMQ
2
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
l r
ICPC勉強会 2015/01/08
• RMQ: Range Minimum Query (区間最小値)
• 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r)
• A[l:r] 中での最小値 A[i] を返す
• 基本的に最大値クエリも同様に処理できる
RMQ
3
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
l r
ICPC勉強会 2015/01/08
• RMQ: Range Minimum Query (区間最小値)
• 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r)
• A[l:r] 中での最小値 A[i] を返す
• 基本的に最大値クエリも同様に処理できる
RMQ
4
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
l r
ICPC勉強会 2015/01/08
RMQを処理するアルゴリズム
• クエリ処理アルゴリズムの計算量:
• 前処理時間
• 1つのクエリの処理時間
5
O(1)O(logn)O(n)
O(n2)
O(nlogn)
O(n)
O( n)
前処理
クエリ処理
ナイーブ

法(1)
O(1)
ナイーブ法(2)
平方

分割
Segment
Tree
Cartesian
Tree + LCA
(割愛)
Sparse Table
ICPC勉強会 2015/01/08
RMQアルゴリズム
• 平方分割
• Segment Tree
• Sparse Table
6
ICPC勉強会 2015/01/08
RMQアルゴリズム
• 平方分割
• Segment Tree
• Sparse Table
7
ICPC勉強会 2015/01/08
バケット分割
• 長さ n の列を長さ s のバケットに分割
• バケットの数 B = n/s
• 各バケットの最小値を O(n) で前計算
• 全体の RMQ クエリは、以下のクエリに分割される
• バケットの区間に対する RMQ クエリ1回
• バケット内部に対する RMQ クエリ2回
8
id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930
a[1:n] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1
b[1:B] 1 3 3 1 4 1 2 2 1 1
ICPC勉強会 2015/01/08
平方分割
• 長さ n の列を長さ n のバケットに分割
• バケットの数 B = n/ n = n
• 全体の RMQ クエリは、以下のクエリに分割される
• バケットの区間に対する RMQ クエリ1回

- n個の最小値インデックスを比較 O( n)
• バケット内部に対する RMQ クエリ2回

- n個の最小値インデックスを比較 O( n)
• 全体でも O( n)
9
id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930
a[1:n] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1
b[1: n] 1 3 1 1 2 1
n
ICPC勉強会 2015/01/08
平方分割の実装 (構築)
10
class Backet{
//sqrtN: backet size, B: the number of backet
int n, sqrtN, B;
vector<int> val, backet;
public:
Backet(vector<int> a):val(a){
n = a.size(); sqrtN = ceil(sqrt(n));
B = (n + sqrtN -1) / sqrtN;
backet.resize(B,INF);
for(int i=0;i<B;i++){
for(int j=sqrtN*i;j<sqrtN*(i+1);j++){
if(j>=n)break;
backet[i] = min(backet[i], val[j]);
}
}
}
ICPC勉強会 2015/01/08
平方分割の実装 (クエリ)
11
int RMQ(int l, int r){
//index in backet
int L = (l + sqrtN -1) / sqrtN + 1, R = r / sqrtN;
int res = INF;
if(L<=R){
for(int i=l;i<sqrtN*L;i++)res = min(res, val[i]);
for(int i=L;i<R;i++)res = min(res, backet[i]);
for(int i=sqrtN*R;i<r;i++)res = min(res, val[i]);
}else{
//interval is included in one backet
for(int i=l;i<r;i++)res = min(res, val[i]);
}
return res;
}
ICPC勉強会 2015/01/08
RMQアルゴリズム
• 平方分割
• Segment Tree
• Sparse Table
12
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• 一見 O(nlogn) 空間に見えて、実は 2n-1 節点
13
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
高さ
logn
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• 構築:葉の方から順に、2つの子の最小値を計算 O(n)
14
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
15
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
16
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
17
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
18
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• 列を2分木の葉に割り当てる
• 各節点は2つの子のうち最小値を保持
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
19
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree
• クエリ:クエリ区間を節点に対応するように分割し、

    その中の最小値を返す O(log n)
• 最初の分割後の下降において、2つの子のうち片方は必ず
区間一致、もしくは範囲外となり、それ以上降りない

= 高々 O(logn) 回の節点参照
20
a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - -
1 1 3 3 6 1 4 -
1 3 1 4
1 1
1
ICPC勉強会 2015/01/08
Segment Tree の実装 (構築)
21
class SegmentTree{
int n;
//represent tree as array
//parent of k : (k-1)/2, child of k : 2*k+1, 2*k+2
vector<int> node;
public:
SegmentTree(vector<int> a){
int n_ = a.size();
//round to power of 2
n=1;
while(n<n_)n*=2;
//initialize tree
node.resize(2*n-1, INF);
//fill data into tree
for(int i=0;i<n_;i++)node[n-1+i] = a[i];
for(int i=n-2;i>=0;i--)node[i] = min(node[2*i+1], node[2*i+2]);
}
ICPC勉強会 2015/01/08
Segment Tree の実装 (クエリ)
22
//return minimum value in [a,b). ( [l,r) is interval in which k is.)
int RMQ(int a,int b,int k=0,int l=0,int r=0){
if(l>=r)r = n;
if(r<=a || b<=l)return INF; //out of range
if(a<=l && r<=b)return node[k]; //interval match
int vl = RMQ(a,b,2*k+1,l,(l+r)/2);
int vr = RMQ(a,b,2*k+2,(l+r)/2,r);
return min(vl,vr);
}
ICPC勉強会 2015/01/08
RMQアルゴリズム
• 平方分割
• Segment Tree
• Sparse Table
23
ICPC勉強会 2015/01/08
Sparse Table
• i 番目から長さ2kの区間の最小値をそれぞれ記憶した
O(n logn)のテーブルを持つ
• 構築: O(n logn)
• S[i][k+1] = min( S[i][k], S[i+2k][k] )
24
i 1 2 3 4 5 6 7 8
A[i] 2 1 8 3 7 2 5 6
S[i][0] 2 1 8 3 7 2 5 6
S[i][1] 1 1 3 3 2 2 5 -
s[i][2] 1 1 2 2 5 - - -
S[i][3] 1 - - - - - - -
ICPC勉強会 2015/01/08
i 1 2 3 4 5 6 7 8
A[i] 2 1 8 3 7 2 5 6
S[i][0] 2 1 8 3 7 2 5 6
S[i][1] 1 1 3 3 2 2 5 -
s[i][2] 1 1 2 2 5 - - -
S[i][3] 1 - - - - - - -
Sparse Table
• i 番目から長さ2kの区間の最小値をそれぞれ記憶した
O(n logn)のテーブルを持つ
• クエリ: O(1)
• RMQ(i, j) = min( S[i][k], S[j-2k+1][k] )
• k = floor( log(j-i) ) ← O(1)で求められると仮定
25
ICPC勉強会 2015/01/08
Sparse Table の実装
26
class SparseTable{
vector< vector<int> > table;
public:
SparseTable(vector<int> a){
int n = a.size(), logn = 31 - __builtin_clz(n);
//initialize table
table.resize(n,vector<int>(logn+1,INF));
for(int i=0;i<n;i++)table[i][0] = a[i];
//construct table
for(int j=0;j<logn;j++){
for(int i=0;i<n;i++){
table[i][j+1] = min(table[i][j], (i+(1<<j)<n)?table[i+(1<<j)][j]:INF);
}
}
}
//return the minimum value in [l, r)
int RMQ(int l, int r){
int ln = 31 - __builtin_clz(r-l);
return min(table[l][ln], table[r-(1<<ln)][ln]);
}
};
ICPC勉強会 2015/01/08
RMQのアルゴリズム
27
空間 前処理 クエリ 動的
平方分割 O(n) O(n) O( n)
○

( O( n) )
Segment
Tree
O(n) O(n) O(logn)
○
( O(logn) )
Sparse
Table
O(n logn) O(n logn) O(1)


( O(n) )
ICPC勉強会 2015/01/08
動的クエリ処理
• 値変更クエリ
• セグメント木:葉の値の変更を親に伝える O(logn)
• 平方分割:バケット最小値を更新 O( n)
• 値挿入クエリ
• セグメント木:クエリの先読みができれば先に な
どで確保しておく
• 平方分割:バケットに追加、サイズが大きくなり
すぎたら分割 O( n)
28
ICPC勉強会 2015/01/08
Segment Tree の実装 (更新)
29
void update(int k, int v){
k += n-1;
node[k] = v;
//traverse from leaf to root
while(k>0){
k = (k-1)/2;
node[k] = min(node[k*2+1],node[k*2+2]);
}
}
ICPC勉強会 2015/01/08
平方分割の実装 (更新)
30
void update(int k, int v){
//update of array
val[k] = v;
//update of backet
int X = k/sqrtN;
backet[X] = INF;
for(int i=sqrtN*X;i<sqrtN*(X+1);i++){
if(i>=n)break;
backet[X] = min(backet[X], val[i]);
}
}
ICPC勉強会 2015/01/08
その他クエリ処理
• セグメント木 (平方分割) は他にも様々な問題に利用可能
• 区間和/積、区間GCD/LCM、etc...
• 結合則が成り立つ演算なら基本的にOK
• 区間和に対するクエリに特化した BIT (Binary Index Tree
= Fenwick Tree) という構造もある (そのうち紹介)
• 1次元 (列) を多次元に拡張することもできる (そのうち紹介)
• 遅延更新というテクニックで、さらに幅広いクエリを処理
できる (そのうち紹介)
31
ICPC勉強会 2015/01/08
まとめ
• RMQ を処理する典型的アルゴリズムの紹介
• 平方分割
• セグメント木
• Sparse Table
• (一部は) 動的なデータの変更にも対応できる
• これらのアルゴリズム (データ構造) は他の問題に
も幅広く応用される
32

More Related Content

What's hot

プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~Takuya Akiba
 
AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説AtCoder Inc.
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)AtCoder Inc.
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Inc.
 
AtCoder Beginner Contest 022 解説
AtCoder Beginner Contest 022 解説AtCoder Beginner Contest 022 解説
AtCoder Beginner Contest 022 解説AtCoder Inc.
 
AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説AtCoder Inc.
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説AtCoder Inc.
 
AtCoder Beginner Contest 021 解説
AtCoder Beginner Contest 021 解説AtCoder Beginner Contest 021 解説
AtCoder Beginner Contest 021 解説AtCoder Inc.
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
At coder regular contest 013 解説
At coder regular contest 013 解説At coder regular contest 013 解説
At coder regular contest 013 解説光喜 濱屋
 
AtCoder Regular Contest 037 解説
AtCoder Regular Contest 037 解説AtCoder Regular Contest 037 解説
AtCoder Regular Contest 037 解説AtCoder Inc.
 
AtCoder Regular Contest 032 解説
AtCoder Regular Contest 032 解説AtCoder Regular Contest 032 解説
AtCoder Regular Contest 032 解説AtCoder Inc.
 
AtCoder Beginner Contest 024 解説
AtCoder Beginner Contest 024 解説AtCoder Beginner Contest 024 解説
AtCoder Beginner Contest 024 解説AtCoder Inc.
 
AtCoder Regular Contest 039 解説
AtCoder Regular Contest 039 解説AtCoder Regular Contest 039 解説
AtCoder Regular Contest 039 解説AtCoder Inc.
 

What's hot (20)

プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
 
双対性
双対性双対性
双対性
 
動的計画法を極める!
動的計画法を極める!動的計画法を極める!
動的計画法を極める!
 
Convex Hull Trick
Convex Hull TrickConvex Hull Trick
Convex Hull Trick
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説AtCoder Beginner Contest 029 解説
AtCoder Beginner Contest 029 解説
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説
 
AtCoder Beginner Contest 022 解説
AtCoder Beginner Contest 022 解説AtCoder Beginner Contest 022 解説
AtCoder Beginner Contest 022 解説
 
AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説AtCoder Beginner Contest 025 解説
AtCoder Beginner Contest 025 解説
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説
 
abc032
abc032abc032
abc032
 
AtCoder Beginner Contest 021 解説
AtCoder Beginner Contest 021 解説AtCoder Beginner Contest 021 解説
AtCoder Beginner Contest 021 解説
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
At coder regular contest 013 解説
At coder regular contest 013 解説At coder regular contest 013 解説
At coder regular contest 013 解説
 
AtCoder Regular Contest 037 解説
AtCoder Regular Contest 037 解説AtCoder Regular Contest 037 解説
AtCoder Regular Contest 037 解説
 
AtCoder Regular Contest 032 解説
AtCoder Regular Contest 032 解説AtCoder Regular Contest 032 解説
AtCoder Regular Contest 032 解説
 
AtCoder Beginner Contest 024 解説
AtCoder Beginner Contest 024 解説AtCoder Beginner Contest 024 解説
AtCoder Beginner Contest 024 解説
 
AtCoder Regular Contest 039 解説
AtCoder Regular Contest 039 解説AtCoder Regular Contest 039 解説
AtCoder Regular Contest 039 解説
 

Similar to RMQ クエリ処理

Ibisml2011 06-20
Ibisml2011 06-20Ibisml2011 06-20
Ibisml2011 06-20Yasuo Tabei
 
Cvim tutorial2 03_06_wk77_110220-0546
Cvim tutorial2 03_06_wk77_110220-0546Cvim tutorial2 03_06_wk77_110220-0546
Cvim tutorial2 03_06_wk77_110220-0546Wataru Kishimoto
 
200514material minami
200514material minami200514material minami
200514material minamiRCCSRENKEI
 
各言語の k-means 比較
各言語の k-means 比較各言語の k-means 比較
各言語の k-means 比較y-uti
 
アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法nitoyon
 
論文紹介:The wavelet matrix
論文紹介:The wavelet matrix論文紹介:The wavelet matrix
論文紹介:The wavelet matrixYuki Igarashi
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Toshiaki Maki
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeMasahiro Tanaka
 
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強Kiyoshi Ogawa
 
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出レコードリンケージに基づく科研費分野-WoS分野マッピングの導出
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出National Institute of Informatics
 
2010 in-depth-v11
2010 in-depth-v112010 in-depth-v11
2010 in-depth-v11kmiyako
 
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法kt.mako
 
Rによるデータサイエンス:12章「時系列」
Rによるデータサイエンス:12章「時系列」Rによるデータサイエンス:12章「時系列」
Rによるデータサイエンス:12章「時系列」Nagi Teramo
 
ソフトウェア自動チューニング研究紹介
ソフトウェア自動チューニング研究紹介ソフトウェア自動チューニング研究紹介
ソフトウェア自動チューニング研究紹介Takahiro Katagiri
 
BigQuery勉強会 Standard SQL Dialect
BigQuery勉強会 Standard SQL DialectBigQuery勉強会 Standard SQL Dialect
BigQuery勉強会 Standard SQL DialectKen Morishita
 
Nagoya.R #12 入門者講習
Nagoya.R #12 入門者講習Nagoya.R #12 入門者講習
Nagoya.R #12 入門者講習Yusaku Kawaguchi
 

Similar to RMQ クエリ処理 (20)

Ibisml2011 06-20
Ibisml2011 06-20Ibisml2011 06-20
Ibisml2011 06-20
 
Cvim tutorial2 03_06_wk77_110220-0546
Cvim tutorial2 03_06_wk77_110220-0546Cvim tutorial2 03_06_wk77_110220-0546
Cvim tutorial2 03_06_wk77_110220-0546
 
200514material minami
200514material minami200514material minami
200514material minami
 
各言語の k-means 比較
各言語の k-means 比較各言語の k-means 比較
各言語の k-means 比較
 
アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法
 
Tokyo r27
Tokyo r27Tokyo r27
Tokyo r27
 
論文紹介:The wavelet matrix
論文紹介:The wavelet matrix論文紹介:The wavelet matrix
論文紹介:The wavelet matrix
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrake
 
HiRoshimaR3_IntroR
HiRoshimaR3_IntroRHiRoshimaR3_IntroR
HiRoshimaR3_IntroR
 
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
STARC RTL設計スタイルガイドによるVerilog HDL並列記述の補強
 
ipsjifat201909
ipsjifat201909ipsjifat201909
ipsjifat201909
 
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出レコードリンケージに基づく科研費分野-WoS分野マッピングの導出
レコードリンケージに基づく科研費分野-WoS分野マッピングの導出
 
2010 in-depth-v11
2010 in-depth-v112010 in-depth-v11
2010 in-depth-v11
 
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法
検索評価ツールキットNTCIREVALを用いた様々な情報アクセス技術の評価方法
 
Rによるデータサイエンス:12章「時系列」
Rによるデータサイエンス:12章「時系列」Rによるデータサイエンス:12章「時系列」
Rによるデータサイエンス:12章「時系列」
 
ソフトウェア自動チューニング研究紹介
ソフトウェア自動チューニング研究紹介ソフトウェア自動チューニング研究紹介
ソフトウェア自動チューニング研究紹介
 
BigQuery勉強会 Standard SQL Dialect
BigQuery勉強会 Standard SQL DialectBigQuery勉強会 Standard SQL Dialect
BigQuery勉強会 Standard SQL Dialect
 
Nagoya.R #12 入門者講習
Nagoya.R #12 入門者講習Nagoya.R #12 入門者講習
Nagoya.R #12 入門者講習
 

More from HCPC: 北海道大学競技プログラミングサークル

More from HCPC: 北海道大学競技プログラミングサークル (20)

写像 12 相
写像 12 相写像 12 相
写像 12 相
 
ACPC 2017 Day3 F: 掛け算は楽しい
ACPC 2017 Day3 F: 掛け算は楽しいACPC 2017 Day3 F: 掛け算は楽しい
ACPC 2017 Day3 F: 掛け算は楽しい
 
ACPC 2017 Day3 D: 優柔不断
ACPC 2017 Day3 D: 優柔不断ACPC 2017 Day3 D: 優柔不断
ACPC 2017 Day3 D: 優柔不断
 
ACPC 2019 Day3 G: Restricted DFS
ACPC 2019 Day3 G: Restricted DFSACPC 2019 Day3 G: Restricted DFS
ACPC 2019 Day3 G: Restricted DFS
 
ACPC 2019 Day3 F: 部分文字列分解
ACPC 2019 Day3 F: 部分文字列分解ACPC 2019 Day3 F: 部分文字列分解
ACPC 2019 Day3 F: 部分文字列分解
 
ACPC 2019 Day3 E: 総和の切り取り
ACPC 2019 Day3 E: 総和の切り取りACPC 2019 Day3 E: 総和の切り取り
ACPC 2019 Day3 E: 総和の切り取り
 
ACPC 2019 Day3 B: パフェ
ACPC 2019 Day3 B: パフェACPC 2019 Day3 B: パフェ
ACPC 2019 Day3 B: パフェ
 
ACPC 2019 Day3 A: 間違い探し
ACPC 2019 Day3 A: 間違い探しACPC 2019 Day3 A: 間違い探し
ACPC 2019 Day3 A: 間違い探し
 
HUPC 2019 Day2 G: 木
HUPC 2019 Day2 G: 木HUPC 2019 Day2 G: 木
HUPC 2019 Day2 G: 木
 
HUPC 2019 Day2 E: ジャム
HUPC 2019 Day2 E: ジャムHUPC 2019 Day2 E: ジャム
HUPC 2019 Day2 E: ジャム
 
HUPC 2019 Day2 H: Revenge of UMG
HUPC 2019 Day2 H: Revenge of UMGHUPC 2019 Day2 H: Revenge of UMG
HUPC 2019 Day2 H: Revenge of UMG
 
HUPC 2019 Day2 F: MOD Rush
HUPC 2019 Day2 F: MOD RushHUPC 2019 Day2 F: MOD Rush
HUPC 2019 Day2 F: MOD Rush
 
HUPC 2019 Day2 C: 串刺し
HUPC 2019 Day2 C: 串刺しHUPC 2019 Day2 C: 串刺し
HUPC 2019 Day2 C: 串刺し
 
HUPC 2019 Day1 F: グリッドの番号
HUPC 2019 Day1 F: グリッドの番号HUPC 2019 Day1 F: グリッドの番号
HUPC 2019 Day1 F: グリッドの番号
 
HUPC 2019 Day1 E: 最短経路の復元
HUPC 2019 Day1 E: 最短経路の復元HUPC 2019 Day1 E: 最短経路の復元
HUPC 2019 Day1 E: 最短経路の復元
 
HUPC 2019 Day1 D: 貪欲が最適?
HUPC 2019 Day1 D: 貪欲が最適?HUPC 2019 Day1 D: 貪欲が最適?
HUPC 2019 Day1 D: 貪欲が最適?
 
HUPC 2019 Day1 C: 短絡評価
HUPC 2019 Day1 C: 短絡評価HUPC 2019 Day1 C: 短絡評価
HUPC 2019 Day1 C: 短絡評価
 
HUPC 2019 Day1 B: 自身の 2 倍
HUPC 2019 Day1 B: 自身の 2 倍HUPC 2019 Day1 B: 自身の 2 倍
HUPC 2019 Day1 B: 自身の 2 倍
 
HUPC 2019 Day1 A: four tea
HUPC 2019 Day1 A: four teaHUPC 2019 Day1 A: four tea
HUPC 2019 Day1 A: four tea
 
プログラミングコンテスト基礎テクニック
プログラミングコンテスト基礎テクニックプログラミングコンテスト基礎テクニック
プログラミングコンテスト基礎テクニック
 

Recently uploaded

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものです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論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 

Recently uploaded (10)

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 

RMQ クエリ処理

  • 1. ICPC勉強会 2015/01/08 RMQ クエリ処理 北海道大学大学院 情報科学研究科 博士1年 井上 祐馬 1
  • 2. ICPC勉強会 2015/01/08 • RMQ: Range Minimum Query (区間最小値) • 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r) • A[l:r] 中での最小値 A[i] を返す • 基本的に最大値クエリも同様に処理できる RMQ 2 id 1 2 3 4 5 6 A[id] 1 8 2 6 3 5 l r
  • 3. ICPC勉強会 2015/01/08 • RMQ: Range Minimum Query (区間最小値) • 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r) • A[l:r] 中での最小値 A[i] を返す • 基本的に最大値クエリも同様に処理できる RMQ 3 id 1 2 3 4 5 6 A[id] 1 8 2 6 3 5 l r
  • 4. ICPC勉強会 2015/01/08 • RMQ: Range Minimum Query (区間最小値) • 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r) • A[l:r] 中での最小値 A[i] を返す • 基本的に最大値クエリも同様に処理できる RMQ 4 id 1 2 3 4 5 6 A[id] 1 8 2 6 3 5 l r
  • 5. ICPC勉強会 2015/01/08 RMQを処理するアルゴリズム • クエリ処理アルゴリズムの計算量: • 前処理時間 • 1つのクエリの処理時間 5 O(1)O(logn)O(n) O(n2) O(nlogn) O(n) O( n) 前処理 クエリ処理 ナイーブ
 法(1) O(1) ナイーブ法(2) 平方
 分割 Segment Tree Cartesian Tree + LCA (割愛) Sparse Table
  • 8. ICPC勉強会 2015/01/08 バケット分割 • 長さ n の列を長さ s のバケットに分割 • バケットの数 B = n/s • 各バケットの最小値を O(n) で前計算 • 全体の RMQ クエリは、以下のクエリに分割される • バケットの区間に対する RMQ クエリ1回 • バケット内部に対する RMQ クエリ2回 8 id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930 a[1:n] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1 b[1:B] 1 3 3 1 4 1 2 2 1 1
  • 9. ICPC勉強会 2015/01/08 平方分割 • 長さ n の列を長さ n のバケットに分割 • バケットの数 B = n/ n = n • 全体の RMQ クエリは、以下のクエリに分割される • バケットの区間に対する RMQ クエリ1回
 - n個の最小値インデックスを比較 O( n) • バケット内部に対する RMQ クエリ2回
 - n個の最小値インデックスを比較 O( n) • 全体でも O( n) 9 id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930 a[1:n] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1 b[1: n] 1 3 1 1 2 1 n
  • 10. ICPC勉強会 2015/01/08 平方分割の実装 (構築) 10 class Backet{ //sqrtN: backet size, B: the number of backet int n, sqrtN, B; vector<int> val, backet; public: Backet(vector<int> a):val(a){ n = a.size(); sqrtN = ceil(sqrt(n)); B = (n + sqrtN -1) / sqrtN; backet.resize(B,INF); for(int i=0;i<B;i++){ for(int j=sqrtN*i;j<sqrtN*(i+1);j++){ if(j>=n)break; backet[i] = min(backet[i], val[j]); } } }
  • 11. ICPC勉強会 2015/01/08 平方分割の実装 (クエリ) 11 int RMQ(int l, int r){ //index in backet int L = (l + sqrtN -1) / sqrtN + 1, R = r / sqrtN; int res = INF; if(L<=R){ for(int i=l;i<sqrtN*L;i++)res = min(res, val[i]); for(int i=L;i<R;i++)res = min(res, backet[i]); for(int i=sqrtN*R;i<r;i++)res = min(res, val[i]); }else{ //interval is included in one backet for(int i=l;i<r;i++)res = min(res, val[i]); } return res; }
  • 13. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • 一見 O(nlogn) 空間に見えて、実は 2n-1 節点 13 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1 高さ logn
  • 14. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • 構築:葉の方から順に、2つの子の最小値を計算 O(n) 14 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 15. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) 15 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 16. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) 16 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 17. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) 17 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 18. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) 18 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 19. ICPC勉強会 2015/01/08 Segment Tree • 列を2分木の葉に割り当てる • 各節点は2つの子のうち最小値を保持 • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) 19 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 20. ICPC勉強会 2015/01/08 Segment Tree • クエリ:クエリ区間を節点に対応するように分割し、
     その中の最小値を返す O(log n) • 最初の分割後の下降において、2つの子のうち片方は必ず 区間一致、もしくは範囲外となり、それ以上降りない
 = 高々 O(logn) 回の節点参照 20 a[1:n] 1 2 1 3 4 3 5 3 6 7 1 8 4 - - - 1 1 3 3 6 1 4 - 1 3 1 4 1 1 1
  • 21. ICPC勉強会 2015/01/08 Segment Tree の実装 (構築) 21 class SegmentTree{ int n; //represent tree as array //parent of k : (k-1)/2, child of k : 2*k+1, 2*k+2 vector<int> node; public: SegmentTree(vector<int> a){ int n_ = a.size(); //round to power of 2 n=1; while(n<n_)n*=2; //initialize tree node.resize(2*n-1, INF); //fill data into tree for(int i=0;i<n_;i++)node[n-1+i] = a[i]; for(int i=n-2;i>=0;i--)node[i] = min(node[2*i+1], node[2*i+2]); }
  • 22. ICPC勉強会 2015/01/08 Segment Tree の実装 (クエリ) 22 //return minimum value in [a,b). ( [l,r) is interval in which k is.) int RMQ(int a,int b,int k=0,int l=0,int r=0){ if(l>=r)r = n; if(r<=a || b<=l)return INF; //out of range if(a<=l && r<=b)return node[k]; //interval match int vl = RMQ(a,b,2*k+1,l,(l+r)/2); int vr = RMQ(a,b,2*k+2,(l+r)/2,r); return min(vl,vr); }
  • 24. ICPC勉強会 2015/01/08 Sparse Table • i 番目から長さ2kの区間の最小値をそれぞれ記憶した O(n logn)のテーブルを持つ • 構築: O(n logn) • S[i][k+1] = min( S[i][k], S[i+2k][k] ) 24 i 1 2 3 4 5 6 7 8 A[i] 2 1 8 3 7 2 5 6 S[i][0] 2 1 8 3 7 2 5 6 S[i][1] 1 1 3 3 2 2 5 - s[i][2] 1 1 2 2 5 - - - S[i][3] 1 - - - - - - -
  • 25. ICPC勉強会 2015/01/08 i 1 2 3 4 5 6 7 8 A[i] 2 1 8 3 7 2 5 6 S[i][0] 2 1 8 3 7 2 5 6 S[i][1] 1 1 3 3 2 2 5 - s[i][2] 1 1 2 2 5 - - - S[i][3] 1 - - - - - - - Sparse Table • i 番目から長さ2kの区間の最小値をそれぞれ記憶した O(n logn)のテーブルを持つ • クエリ: O(1) • RMQ(i, j) = min( S[i][k], S[j-2k+1][k] ) • k = floor( log(j-i) ) ← O(1)で求められると仮定 25
  • 26. ICPC勉強会 2015/01/08 Sparse Table の実装 26 class SparseTable{ vector< vector<int> > table; public: SparseTable(vector<int> a){ int n = a.size(), logn = 31 - __builtin_clz(n); //initialize table table.resize(n,vector<int>(logn+1,INF)); for(int i=0;i<n;i++)table[i][0] = a[i]; //construct table for(int j=0;j<logn;j++){ for(int i=0;i<n;i++){ table[i][j+1] = min(table[i][j], (i+(1<<j)<n)?table[i+(1<<j)][j]:INF); } } } //return the minimum value in [l, r) int RMQ(int l, int r){ int ln = 31 - __builtin_clz(r-l); return min(table[l][ln], table[r-(1<<ln)][ln]); } };
  • 27. ICPC勉強会 2015/01/08 RMQのアルゴリズム 27 空間 前処理 クエリ 動的 平方分割 O(n) O(n) O( n) ○
 ( O( n) ) Segment Tree O(n) O(n) O(logn) ○ ( O(logn) ) Sparse Table O(n logn) O(n logn) O(1) 
 ( O(n) )
  • 28. ICPC勉強会 2015/01/08 動的クエリ処理 • 値変更クエリ • セグメント木:葉の値の変更を親に伝える O(logn) • 平方分割:バケット最小値を更新 O( n) • 値挿入クエリ • セグメント木:クエリの先読みができれば先に な どで確保しておく • 平方分割:バケットに追加、サイズが大きくなり すぎたら分割 O( n) 28
  • 29. ICPC勉強会 2015/01/08 Segment Tree の実装 (更新) 29 void update(int k, int v){ k += n-1; node[k] = v; //traverse from leaf to root while(k>0){ k = (k-1)/2; node[k] = min(node[k*2+1],node[k*2+2]); } }
  • 30. ICPC勉強会 2015/01/08 平方分割の実装 (更新) 30 void update(int k, int v){ //update of array val[k] = v; //update of backet int X = k/sqrtN; backet[X] = INF; for(int i=sqrtN*X;i<sqrtN*(X+1);i++){ if(i>=n)break; backet[X] = min(backet[X], val[i]); } }
  • 31. ICPC勉強会 2015/01/08 その他クエリ処理 • セグメント木 (平方分割) は他にも様々な問題に利用可能 • 区間和/積、区間GCD/LCM、etc... • 結合則が成り立つ演算なら基本的にOK • 区間和に対するクエリに特化した BIT (Binary Index Tree = Fenwick Tree) という構造もある (そのうち紹介) • 1次元 (列) を多次元に拡張することもできる (そのうち紹介) • 遅延更新というテクニックで、さらに幅広いクエリを処理 できる (そのうち紹介) 31
  • 32. ICPC勉強会 2015/01/08 まとめ • RMQ を処理する典型的アルゴリズムの紹介 • 平方分割 • セグメント木 • Sparse Table • (一部は) 動的なデータの変更にも対応できる • これらのアルゴリズム (データ構造) は他の問題に も幅広く応用される 32