Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
Yuuki Ono
737 views
第22回アルゴリズム勉強会資料
Read more
1
Save
Share
Embed
Embed presentation
Download
Download to read offline
1
/ 90
2
/ 90
3
/ 90
4
/ 90
5
/ 90
6
/ 90
7
/ 90
8
/ 90
9
/ 90
10
/ 90
11
/ 90
12
/ 90
13
/ 90
14
/ 90
15
/ 90
16
/ 90
17
/ 90
18
/ 90
19
/ 90
20
/ 90
21
/ 90
22
/ 90
23
/ 90
24
/ 90
25
/ 90
26
/ 90
27
/ 90
28
/ 90
29
/ 90
30
/ 90
31
/ 90
32
/ 90
33
/ 90
34
/ 90
35
/ 90
36
/ 90
37
/ 90
38
/ 90
39
/ 90
40
/ 90
41
/ 90
42
/ 90
43
/ 90
44
/ 90
45
/ 90
46
/ 90
47
/ 90
48
/ 90
49
/ 90
50
/ 90
51
/ 90
52
/ 90
53
/ 90
54
/ 90
55
/ 90
56
/ 90
57
/ 90
58
/ 90
59
/ 90
60
/ 90
61
/ 90
62
/ 90
63
/ 90
64
/ 90
65
/ 90
66
/ 90
67
/ 90
68
/ 90
69
/ 90
70
/ 90
71
/ 90
72
/ 90
73
/ 90
74
/ 90
75
/ 90
76
/ 90
77
/ 90
78
/ 90
79
/ 90
80
/ 90
81
/ 90
82
/ 90
83
/ 90
84
/ 90
85
/ 90
86
/ 90
87
/ 90
88
/ 90
89
/ 90
90
/ 90
More Related Content
PDF
PFI Christmas seminar 2009
by
Preferred Networks
PDF
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
by
AtCoder Inc.
PPTX
競技プログラミングのためのC++入門
by
natrium11321
PDF
Ibisml2011 06-20
by
Yasuo Tabei
PPTX
純粋関数型アルゴリズム入門
by
Kimikazu Kato
PDF
プログラミングコンテストでのデータ構造
by
Takuya Akiba
PDF
第24回アルゴリズム勉強会資料
by
Yuuki Ono
PDF
第21回アルゴリズム勉強会
by
Yuuki Ono
PFI Christmas seminar 2009
by
Preferred Networks
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
by
AtCoder Inc.
競技プログラミングのためのC++入門
by
natrium11321
Ibisml2011 06-20
by
Yasuo Tabei
純粋関数型アルゴリズム入門
by
Kimikazu Kato
プログラミングコンテストでのデータ構造
by
Takuya Akiba
第24回アルゴリズム勉強会資料
by
Yuuki Ono
第21回アルゴリズム勉強会
by
Yuuki Ono
Similar to 第22回アルゴリズム勉強会資料
PDF
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
by
Kensuke Otsuki
PPTX
AtCoder Beginner Contest 012 解説
by
AtCoder Inc.
PDF
Rブートキャンプ
by
Kosuke Sato
PDF
関数型プログラミング入門 with OCaml
by
Haruka Oikawa
PDF
プログラミングコンテストでの乱択アルゴリズム
by
Takuya Akiba
PPT
Algorithm 速いアルゴリズムを書くための基礎
by
Kenji Otsuka
PDF
プログラミングコンテストでのデータ構造 2 ~動的木編~
by
Takuya Akiba
PDF
RMQ クエリ処理
by
HCPC: 北海道大学競技プログラミングサークル
PDF
ウェーブレット木の世界
by
Preferred Networks
PDF
Sec15 dynamic programming
by
Keisuke OTAKI
PDF
Binary indexed tree
by
HCPC: 北海道大学競技プログラミングサークル
PDF
JOIss2020 発表資料
by
mdkcpp 1015
PDF
AtCoder Regular Contest 030 解説
by
AtCoder Inc.
PPTX
NUPSC招待講演:アルゴリズムで広がる世界
by
Kentaro Imajo
PDF
Nazoki
by
Ken Ogura
PDF
C++0x in programming competition
by
yak1ex
PDF
Wavelet matrix implementation
by
MITSUNARI Shigeo
PDF
JOI春季ステップアップセミナー 2021 講義スライド
by
Kensuke Otsuki
PDF
programming camp 2008, introduction of programming, algorithm
by
Hiro Yoshioka
PDF
CODE THANKS FESTIVAL 2014 A日程 解説
by
AtCoder Inc.
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
by
Kensuke Otsuki
AtCoder Beginner Contest 012 解説
by
AtCoder Inc.
Rブートキャンプ
by
Kosuke Sato
関数型プログラミング入門 with OCaml
by
Haruka Oikawa
プログラミングコンテストでの乱択アルゴリズム
by
Takuya Akiba
Algorithm 速いアルゴリズムを書くための基礎
by
Kenji Otsuka
プログラミングコンテストでのデータ構造 2 ~動的木編~
by
Takuya Akiba
RMQ クエリ処理
by
HCPC: 北海道大学競技プログラミングサークル
ウェーブレット木の世界
by
Preferred Networks
Sec15 dynamic programming
by
Keisuke OTAKI
Binary indexed tree
by
HCPC: 北海道大学競技プログラミングサークル
JOIss2020 発表資料
by
mdkcpp 1015
AtCoder Regular Contest 030 解説
by
AtCoder Inc.
NUPSC招待講演:アルゴリズムで広がる世界
by
Kentaro Imajo
Nazoki
by
Ken Ogura
C++0x in programming competition
by
yak1ex
Wavelet matrix implementation
by
MITSUNARI Shigeo
JOI春季ステップアップセミナー 2021 講義スライド
by
Kensuke Otsuki
programming camp 2008, introduction of programming, algorithm
by
Hiro Yoshioka
CODE THANKS FESTIVAL 2014 A日程 解説
by
AtCoder Inc.
第22回アルゴリズム勉強会資料
1.
第22回アルゴリズム勉強会 @Cafe IKAGAWADO 2014/7/6
2.
アルゴリズム勉強会とは? • 勉強会のコンセプト - 知的好奇心を満たす -
技術力を高める(アイディア力) - 大学や社会人の垣根を超えた交流 - 知識やアルゴリズムを共有する場 を目指す
3.
注意事項 • 言語や開発環境は自由です。 • お好きな言語で実装してください。 " •
ただし、資料はJavaになりますのでご了承ください。 • (スライドの中では省略) 3
4.
注意事項 • 特別、休憩時間は取りません。 1テーマごとに15分毎休憩時間を設けるつもりですが、 自由に休憩時間をとってください。 • 参加費(会場使用費・ドリンク代)は500円となっております。 ドリンクバー形式になってますので、お好きに飲んでください •
TopCoderレーティング割が適用されます。 • グリーンコーダー 400円 • ブルーコーダー 200円 • イエローコーダー 以上 0円 4
5.
範囲の探索 今日は、AtCoderの問題を解く感じではなく 今日はテーマに対して深く勉強します。
6.
今日はいつもより難しい アルゴリズムを行います!! 6
7.
純粋な実装を超える! 7
8.
範囲の探索 • ソートされてる範囲[a,b)から値を高速に探そう • 二分探索 " •
範囲[a,b)の最小値を高速に探そう RMQ • Segment Tree " • 範囲[a,b)の和を高速に求めよう • BIT (Binary Indexed Tree)
9.
範囲[a,b) から値を高速に探そう 9
10.
問題 • ソートされてる配列がlist与えられてその長さが2つ以上の区間 [a,b+1)内に 値(list[a]+list[b])/2 (少数切り捨て)が含まれてるような範囲の個数を求め てください。 " •
[a,b+1) は インデックスa以上b+1未満の範囲 (0-based Index) • typoじゃないよ " • 例:[1,2,5] の場合 [1,2],[1,2,5],[2,5] なので1
11.
実装してみましょう 11
12.
純粋な実装では " " " • a~bまで順番に見ていくので 最大 O(n^3) かかります。 " • 探索部分を二分探索にすることで O(n^2
log n) で可能になる。 12
13.
二分探索 " " そのほうめんでは「にぶたん」とか言われてる
14.
二分探索 5 7 12
16 18 20 24 28 a b c 16 16<18 c=(a+b)/2
15.
二分探索 5 7 12
16 18 20 24 28 a b 16 16>12 c
16.
二分探索 5 7 12
16 18 20 24 28 a b 16 16==16 c
17.
リストの中に値 がなくても 使えます。 17
18.
二分探索 5 7 12
16 18 20 24 28 a b 14 14<16 c
19.
二分探索 5 7 12
16 18 20 24 28 a b 14 これ以上縮められなくなったら終了 (aまたはbが変わらなくなったら) みつからなかったということになる。 c 14>12
20.
二分探索 まとめ • 範囲を半分半分に縮めてしぼっていく。 " • リストがソート済みのものに可能。 ソートしても良い場合
O (n log n)でソートしてもOK " • ある値を探す以外とかの応用など可能である。 条件を満たす値を探すなどの応用もある。 20
21.
Segment Tree 21
22.
問題 • 配列でlist与えられて[a,b)内の最小値を求めてください • [a,b) は インデックスa以上b未満の範囲 (0-based
Index) • 例:[5,1,2,4,5] の 範囲[2,4) での最小値は 1 " " • 課題では ありうるすべての範囲と その最小値の和を求めてください。
23.
実装してみましょう 23
24.
• 以下の2つをすることをRMQ (Range
Minimum/Max Query)と 言います。 • ある範囲の中から最小値を探す処理 • ある範囲の最小値を更新する処理 • RMQというと、たいてい上の2つの処理を何度もする。 • 純粋な実装の場合 • 更新する処理 list[x]=value で O(1) • 探す処理 for(int i=a,i<b;i++) で O(n) 24
25.
Segment Tree 25
26.
26 min(a[0]~a[7]) a[0]~a[3] a[4]~a[7] a[0]~ a[1] a[2]~ a[3] a[0] a[1]
a[2] a[3] a[4]~ a[5] a[6]~ a[7] a[4] a[5] a[6] a[7] それぞれ範囲の最小値とする
27.
データ構造 27
28.
28 b[1] b[2] b[3] b[4] b[5] b[8]
b[9] b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15]
29.
データの作り方 29
30.
Segment Treeの作り方 • 完全二分木(にした方がいい)のでノード数を調整する。 •
一番下(根)のノード数が配列数より同じか大きくとる • 配列数が5個なら • 1+2+4+8 =15 個の要素の配列を用意する。 • すべての要素を最大値で埋める 30
31.
31 b[1] b[2] b[3] b[4] b[5] b[8]
b[9] b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[0]=5 をセットする場合 index=(ノード数)-8+0 更新
32.
32 b[1] b[2] b[3] b[4] b[5] 5
b[9] b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[0]=5 をセットする場合 b[8]=min(b[8],5) 更新
33.
33 b[1] b[2] b[3] b[4] b[5] 5
b[9] b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[0]=5 をセットする場合 index= index/2 更新
34.
34 b[1] b[2] b[3] 5 b[5] 5
b[9] b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[0]=5 をセットする場合 index= index/2 更新
35.
35 5 5 b[3] 5 b[5] 5
3 b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[1]=3 をセットする場合 更新
36.
36 5 5 b[3] 3 min(5,3) b[5] 5 3
b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[1]=3 をセットする場合 更新 index= index/2
37.
37 3 3 b[3] 3 min(5,3) b[5] 5 3
b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[1]=3 をセットする場合 更新
38.
38 3 3 8 3 4 5
3 4 20 10 8 10 12 8 9 すべてのセットを行ったら(例えば)
39.
範囲の探索 " " 再帰を利用します。 ちょっと難しいです。 39
40.
40 3 3 8 3 4 5
3 4 20 10 8 10 12 8 9 [1,5) の範囲に対して検索を行う時
41.
41 3 3 8 3 4 5
3 4 20 10 8 10 12 8 9 [1,5) の範囲に対して検索を行う時
42.
42 3 3 8 3 4 5
3 4 20 10 8 10 12 8 9 [1,5) の範囲に対して検索を行う時
43.
43 3 3 8 3 4 5
3 4 20 10 8 10 12 8 9 [1,5) の範囲に対して検索を行う時
44.
44 [1,5) の範囲に対して検索を行う時 getMin(int left,int
right,int a,int b,int index) " のような関数を作る。 ・範囲 [a,b)の中に [left,right)が完全に含ま れている時 b[index]を返す。 " " 4 3 10
45.
45 [1,5) の範囲に対して検索を行う時 getMin(int left,int
right,int a,int b,int index) " のような関数を作る。 ・範囲 [a,b)が[left,right)が全く含まれてない 時 無効な値を返す。(例えばMAX_INTEGER) " "
46.
46 [1,5) の範囲に対して検索を行う時 getMin(int left,int
right,int a,int b,int index) " のような関数を作る。 ・範囲 [a,b)が[left,right)が一部でも含まれてたら 再帰的に関数を2回呼び出す。 (その最小値を計算する) " int m1=getMin(left,(left+right)/2,a,b,index*2) int m2=getMin((left+right)/2,right,a,b,index*2+1) return min (m1,m2) "
47.
47 3 3 8 これに相当します。 a b left
right
48.
ワンポイント • [a,b) の理由
——- [0,4) だとする • もし [a,b] だと 領域を分割する時 • [0,3] だと [0,1],[2,3] としないといけない • [0,4)とすると • [0,2) ,[2,4) とかけて少しスマート " • これに習い、stringのsubstringなども [a,b) になっている。 48
49.
ワンポイント • Segment Treeの配列が1から始まってる理由 " •
ノードの下をたどるときに index*2+1, index*2+2 にしないといけないため、操作が少し面倒。 " • 1からにすると index*2,index*2+1 にできてスマート 49
50.
計算量 • xi=vを入れる O(log n) •
[a,b)の最小値を調べる O(log n) " • 上はいつでも任意の順番でいつでも行える。 (最初Treeを構築したら終わりではない) 50
51.
範囲[a,b)の和を高速に求めよう 51
52.
問題 • 配列でlist与えられて[a,b)内の合計値を求めてください • [a,b) は インデックスa以上b未満の範囲 (0-based
Index) • 例:[5,1,2,4,5] の 範囲[2,4) での合計値は 3 " " • 課題では ありうるすべての範囲の和を求めてください。
53.
ヒント 53
54.
Segment Treeを使います 54
55.
55 sum(a[0]~a[7]) a[0]~a[3] a[4]~a[7] a[0]~ a[1] a[2]~ a[3] a[0] a[1]
a[2] a[3] a[4]~ a[5] a[6]~ a[7] a[4] a[5] a[6] a[7] それぞれ範囲の和とする
56.
56 5 5 b[3] 8 5+3 b[5] 5 3
b[10] b[11] b[6] b[7] b[12] b[13] b[14] b[15] 元の配列 a[1]=3 をセットする場合 minの ところを和 に変える index= index/2
57.
57 67 32 39 8 24 5
3 4 20 22 17 10 12 8 9 すべてのセットを行ったら(例えば)
58.
58 [1,6) の範囲に対して検索を行う時 getSum(int left,int
right,int a,int b,int index) " のような関数を作る。 ・範囲 [a,b)が[left,right)が一部でも含まれてたら 再帰的に関数を2回呼び出す。 " int m1=getSum(left,(left+right)/2,a,b,index*2) int m2=getSum((left+right)/2,right,a,b,index*2+1) return m1+m2 "
59.
これでも大丈夫 59
60.
更に良い方法があります 60
61.
例えば • 範囲[2,4) の部分和を求めるとき、 S(n) を
[0,n)の部分和の関数とすると S ( x ) - S ( y ) で表すことができる 。 " " • xとyの値は何でしょう? 61
62.
範囲[2,4) の部分和は S(4) - S
(2) で求めることが出来ます。 62
63.
Sはどうやって作る? 63
64.
BIT Binary Indexed Tree 64
65.
65 67 32 39 8 24 5
3 4 20 22 17 10 12 8 9
66.
66 67 32 8 5 4 22 10 8
67.
データ構造 67
68.
68 b[8] b[4] b[2] b[1] b[3] b[6] b[5] b[7]
69.
indexの性質 69
70.
70 b[8] b[4] b[2] b[1] b[3] b[6] b[5] b[7] 各
index番号は 各範囲の最後の要素になっている
71.
71 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] 各
index番号を2進数で表現したときを最後から連続する0の数が高さの同じになる。
72.
データの作り方 72
73.
BITの作り方 • これもやっぱりノード数を調整する。 • 配列数が5個なら •
1,2,4,8 で ノード数8にする。 " " • 初期化作業が大事 73
74.
74 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] a[0]
= 5 のとき 更新対象 更新対象 更新対象 更新対象
75.
75 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] a[4]
= 3 のとき 更新対象 更新対象 更新対象
76.
76 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] 更新の求め方は,
対象のindex +1 の2進数表現の最後のbitを足すことで求められる 更新対象 更新対象 更新対象
77.
データの探し方 77
78.
78 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] S(5)
= [0,5) の部分和を求める時 " 元の配列とBITはindexが1ずれてるのに注意
79.
79 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] S(5)
からBITでは 5が最後の要素で2進数表現では 101 なので b[101] の要素を見る 次に b[100]の要素を見れれば良い
80.
80 b[1000] b[100] b[10] b[1] b[11] b[110] b[101] b[111] この求め方は
各ビットで1があるものを下から順番に0にしたもの なっている 101 -> 100 など
81.
うまくできてます。 81
82.
ビットテクニック! " " 他でも使えるビットテクニックです。 " 忘れても普通にforなどでしてもいいと思います。 82
83.
最後の1になってるbitを0にする • 元の値 14
-> 1110 " • 1を引く 13 -> 1101 " • bit andを取る -> 1100 83 できました!
84.
最後の1になっているものだけ取り出す • 元の値 14
-> 1110 " • 1を引く 13 -> 1101 " • bit andを取る -> 1100 " • 元の値と bit xorを取る 0010 84 できました!
85.
このテクニックを使えば BITが使えます。 85
86.
[a,b)の和を求めるには? • bit.getSum(a)で[0,a) • bit.getSum(b)で[0,b) " •
なので最終的に bit.getSum(b)-bit.getSum(a) をすると[a,b)の和を求めることができる。 86
87.
計算量 • xiにvを入れる O(log n) •
[a,b)の総和を調べる O(log n) " • 上はいつでも任意の順番で行える。 87
88.
これらが使える問題 • AtCoder ARC
#026 C-蛍光灯 • http://arc026.contest.atcoder.jp/tasks/arc026_3 • Segment Tree " • AtCoder ARC #014 D - grepマスター • http://arc014.contest.atcoder.jp/tasks/arc014_4 • 2分探索 88
89.
参考・引用資料 • プログラミングコンテストでのデータ構造 SlideShare 秋葉
拓哉 / (iwi) • http://www.slideshare.net/iwiwi/ss-3578491 89
90.
以上お疲れ様でした。 90
Download