Slide 1

Slide 1 text

第14回情報オリンピック  春合宿  day4   Walls  別解解説 ⼆二階堂建⼈人(snuke)

Slide 2

Slide 2 text

⼩小課題2 最初、防壁の左端が全部  0

Slide 3

Slide 3 text

下ごしらえ 壁を⻑⾧長さでソートしておく

Slide 4

Slide 4 text

下ごしらえ どの時点でも⼭山型になっている   (凹んでいたりしない)

Slide 5

Slide 5 text

レーザー レーザーが来た時は、   ・上  n  個を左揃え   ・上  n  個を右揃え   のどちらかが起こる

Slide 6

Slide 6 text

レーザー レーザーが来た時は、   ・上  n  個を左揃え   ・上  n  個を右揃え   のどちらかが起こる

Slide 7

Slide 7 text

レーザー レーザーが来た時は、   ・上  n  個を左揃え   ・上  n  個を右揃え   のどちらかが起こる

Slide 8

Slide 8 text

segtree segtreeを作ってみる   ノードに持たせる値は何にするか

Slide 9

Slide 9 text

ノードに持たせる値 とりあえず、state,pos  を⽤用意する   ・state  =  1  なら、区間内の防壁がposで左揃えされている   ・state  =  2  なら、区間内の防壁がposで右揃えされている   ・state  =  -‐‑‒1  なら、区間は揃っていない (state,pos)  =  (-‐‑‒1,-‐‑‒1) 2,10 -‐‑‒1,-‐‑‒1 2,10 2,10 -‐‑‒1,-‐‑‒1 1,0 2,10 2,10 2,10 2,10 1,4 1,2 1,0 1,0

Slide 10

Slide 10 text

更更新⽅方法 state  =  1  の場合(区間が全てposで左揃え)   ・区間が全てpi で左揃えされる場合:普通に更更新   ・区間が全てpi で右揃えされる場合:普通に更更新   ・区間が揃わない場合:
     stateを  -‐‑‒1  にして、左の⼦子に潜り、       ・左の⼦子が揃わなかった場合:右の⼦子には潜らない       ・左の⼦子が揃った場合:右の⼦子にも潜る   (state  =  2  の場合(区間が全てposで右揃え)も同様) =state,posの組が同じ

Slide 11

Slide 11 text

更更新⽅方法 state  =  -‐‑‒1  の場合(区間が揃っていない)   ・左の⼦子に潜る     ・左の⼦子が揃わなかった場合:右の⼦子には潜らない     ・左の⼦子が揃った場合:右の⼦子にも潜る   ・潜った後、
   ・左右の⼦子が揃った場合:state,posを⼦子と同じにする     ・左右の⼦子が揃わなかった場合:stateを-‐‑‒1にする

Slide 12

Slide 12 text

更更新⽅方法 state  =  1  の場合(区間が全てposで左揃え)   ・区間が全てpi で左揃えされる場合:普通に更更新   ・区間が全てpi で右揃えされる場合:普通に更更新   ・区間が揃わない場合:
     stateを  -‐‑‒1  にして、左の⼦子に潜り、       ・左の⼦子が揃わなかった場合:右の⼦子には潜らない       ・左の⼦子が揃った場合:右の⼦子にも潜る   →  ノードに  w  =「区間内の防壁の⻑⾧長さの最⼤大」も
     持たせておくとよい(⻑⾧長いのが揃えば短いのも揃う)

Slide 13

Slide 13 text

答えを求める 答えを求めるためには、   各ノードになにを持たせればいいか  

Slide 14

Slide 14 text

各移動の⻑⾧長さ 左揃え  →  左揃え(右揃え  →  右揃え)   p 移動量量:pos  -‐‑‒  p pos wi

Slide 15

Slide 15 text

左揃え  →  右揃え(右揃え  →  左揃え)   pos wi 各移動の⻑⾧長さ 移動量量:p  -‐‑‒  pos  -‐‑‒  wi  +  1 p

Slide 16

Slide 16 text

答えを求める ・pos  -‐‑‒  p   ・p  -‐‑‒  pos  -‐‑‒  wi  +  1   をいくつか⾜足したものが答え   各防壁の答えは、   ・x  +  wi  *  y   という形で表せそう

Slide 17

Slide 17 text

答えを求める segtreeの各ノードに、sum,cnt  という値を持たせる   答えは「sumの和  +  cntの和  *  wi 」   更更新は   ・左揃え→左揃え:sum  +=  pos  -‐‑‒  p   ・左揃え→右揃え:sum  +=  p  -‐‑‒  pos  +  1,  cnt  -‐‑‒=  wi   とすればいい

Slide 18

Slide 18 text

まとめ segtreeを作り、ノードには以下の値を持たせる   ・state,pos:左揃い・右揃い・不不揃い、揃った場所   ・w:防壁の最⼤大⻑⾧長区間(全て揃うかを判定するため)   ・sum,cnt:答えを計算するための値   更更新は、   ・state,posを更更新するついでにsum,cntを更更新する   ・state=1,2(揃っている)なら普通に更更新   ・state=-‐‑‒1(不不揃い)なら⼦子に潜る   →  計算量量は?

Slide 19

Slide 19 text

計算量量 state  =  -‐‑‒1  の場合(区間が揃っていない)   ・左の⼦子に潜る     ・左の⼦子が揃わなかった場合:右の⼦子には潜らない     ・左の⼦子が揃った場合:右の⼦子にも潜る   ・潜った後、
   ・左右の⼦子が揃った場合:state,posを⼦子と同じにする     ・左右の⼦子が揃わなかった場合:stateを-‐‑‒1にする state  =  1  の場合(区間が全てposで左揃え)   ・区間が全てp i で左揃えされる場合:普通に更更新   ・区間が全てp i で右揃えされる場合:普通に更更新   ・区間が揃わない場合:
     stateを  -‐‑‒1  にして、左の⼦子に潜り、       ・左の⼦子が揃わなかった場合:右の⼦子には潜らない       ・左の⼦子が揃った場合:右の⼦子にも潜る   (state  =  2  の場合(区間が全てposで右揃え)も同様) ポイント   ・state  =  -‐‑‒1  なら潜る   ・stateによらず、まず左の⼦子に潜り、     ・左の⼦子が揃わなかった場合:右の⼦子には潜らない     ・左の⼦子が揃った場合:右の⼦子にも潜る

Slide 20

Slide 20 text

計算量量 ⾚赤い線のようにsegtree上を動きます   たくさんのノードを辿ることもありそうに⾒見見えます  

Slide 21

Slide 21 text

計算量量 ◯で囲ったような部分、   つまり左も右もがっつり潜る部分の個数を  x  とすると、   O(x  *  segtreeの⾼高さ(=logN))  で抑えられそうです   ※ここのように、潜った直後に帰ってくる場所は含まない  

Slide 22

Slide 22 text

計算量量 ・◯で囲ったような部分のstateは  -‐‑‒1  のはず  

Slide 23

Slide 23 text

計算量量 ・右の⼦子にも潜るということは、左の⼦子は全部揃っている   →  ◯の部分で右に潜ったということは、       △のstateが  -‐‑‒1  から  1  か  2  になる  

Slide 24

Slide 24 text

計算量量 つまり左も右もがっつり潜る部分の個数を  x  とすると、   O(x  *  segtreeの⾼高さ=(logN))  で抑えられそうです   ・潜るノードの個数が  O(log  N)  回増えるときは、     state=-‐‑‒1  のノードが  1  つ減る!   ・さらに、stateが  1  か  2  から  -‐‑‒1  になるノードは、1つの
   レーザーにつき、O(log  N)  個     →  そのような場所は、
       i  =  iより左は全部揃い、iより右は揃わない
     というような  i  を含む区間のみ

Slide 25

Slide 25 text

計算量量 ・潜るノードの個数が  O(log  N)  回増えるときは、     必ず  state=-‐‑‒1  のノードが  1  つ減る!   ・さらに、stateが  1  か  2  から  -‐‑‒1  になるノードは、1つの
   レーザーにつき、O(log  N)  個   潜るノードの個数が増える回数  ≦  state=-‐‑‒1のノードが減る個数   state=-‐‑‒1のノードが減る個数  ≦  state=-‐‑‒1のノードが増える個数   state=-‐‑‒1のノードが増える個数  ≦  O(log  N)*レーザーの個数   つまり、   潜るノードの個数が増える回数  ≦  O(log  N)*レーザーの個数!   →  ならし計算量量が  O(log^2  N)  になった!

Slide 26

Slide 26 text

⼩小課題2 このように、   保留留した頂点を後で潜る、遅延更更新の発展系のような⼿手法   を使うと、O(M  log^2  N)  で解けた!   参考   http://snuke.hatenablog.com/entry/2014/08/02/202210

Slide 27

Slide 27 text

⼩小課題3 初期位置がめちゃくちゃなので、そのままだとダメ   初期位置が  0  だったときとの差分を計算してやると良良い