第22回アルゴリズム勉強会資料
- 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
- 14. 二分探索
5 7 12 16 18 20 24 28
a b
c
16
16<18
c=(a+b)/2
- 19. 二分探索
5 7 12 16 18 20 24 28
a b
14
これ以上縮められなくなったら終了
(aまたはbが変わらなくなったら)
みつからなかったということになる。
c 14>12
- 24. • 以下の2つをすることをRMQ (Range Minimum/Max Query)と
言います。
• ある範囲の中から最小値を探す処理
• ある範囲の最小値を更新する処理
• RMQというと、たいてい上の2つの処理を何度もする。
• 純粋な実装の場合
• 更新する処理 list[x]=value で O(1)
• 探す処理 for(int i=a,i<b;i++) で O(n)
24
- 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)
"
- 48. ワンポイント
• [a,b) の理由 ——- [0,4) だとする
• もし [a,b] だと 領域を分割する時
• [0,3] だと [0,1],[2,3] としないといけない
• [0,4)とすると
• [0,2) ,[2,4) とかけて少しスマート
"
• これに習い、stringのsubstringなども [a,b) になっている。
48
- 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
"
- 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