Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JOI2015-sp-day4-walls-anothersolution
Search
snuke
May 02, 2015
Programming
0
240
JOI2015-sp-day4-walls-anothersolution
第14回情報オリンピック春合宿day4 Walls 別解
snuke
May 02, 2015
Tweet
Share
More Decks by snuke
See All by snuke
puzzleLT.pdf
snuke
0
710
JOI2015-2016 春合宿 day 2 Sandwich 解説
snuke
0
310
JOI2014 春合宿 day 2 スタンプラリー 解説
snuke
0
210
NPCA合宿きょーぷろ講義
snuke
0
360
JOI 2013 春合宿 day4-1 messenger 解説
snuke
0
370
CodeForces#162 Div1-E
snuke
0
330
CodeForces162 Div1-E
snuke
3
16k
SRM 555 Div 1 easy, Div 2 medium
snuke
1
460
SRM 555 Div 1 hard
snuke
1
550
Other Decks in Programming
See All in Programming
外接に惑わされない自システムの処理時間SLIをOpenTelemetryで実現した話
kotaro7750
0
230
AI駆動開発ライフサイクル(AI-DLC)のホワイトペーパーを解説
swxhariu5
0
210
퇴근 후 1억이 거래되는 서비스 만들기 | 내가 AI를 사용하는 방법
maryang
2
510
Making Angular Apps Smarter with Generative AI: Local and Offline-capable
christianliebel
PRO
0
110
Temporal Knowledge Graphで作る! 時間変化するナレッジを扱うAI Agentの世界
po3rin
5
1.3k
開発組織の戦略的な役割と 設計スキル向上の効果
masuda220
PRO
10
2.1k
Blazing Fast UI Development with Compose Hot Reload (droidcon London 2025)
zsmb
0
490
Register is more than clipboard
satorunooshie
1
430
Private APIの呼び出し方
kishikawakatsumi
2
740
SidekiqでAIに商品説明を生成させてみた
akinko_0915
0
120
CSC305 Lecture 14
javiergs
PRO
0
250
AI 駆動開発におけるコミュニティと AWS CDK の価値
konokenj
5
360
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
116
20k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
For a Future-Friendly Web
brad_frost
180
10k
Agile that works and the tools we love
rasmusluckow
331
21k
Gamification - CAS2011
davidbonilla
81
5.5k
The Pragmatic Product Professional
lauravandoore
36
7k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8k
4 Signs Your Business is Dying
shpigford
186
22k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6k
RailsConf 2023
tenderlove
30
1.3k
Side Projects
sachag
455
43k
Transcript
第14回情報オリンピック 春合宿 day4 Walls 別解解説 ⼆二階堂建⼈人(snuke)
⼩小課題2 最初、防壁の左端が全部 0
下ごしらえ 壁を⻑⾧長さでソートしておく
下ごしらえ どの時点でも⼭山型になっている (凹んでいたりしない)
レーザー レーザーが来た時は、 ・上 n 個を左揃え ・上 n 個を右揃え
のどちらかが起こる
レーザー レーザーが来た時は、 ・上 n 個を左揃え ・上 n 個を右揃え
のどちらかが起こる
レーザー レーザーが来た時は、 ・上 n 個を左揃え ・上 n 個を右揃え
のどちらかが起こる
segtree segtreeを作ってみる ノードに持たせる値は何にするか
ノードに持たせる値 とりあえず、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
更更新⽅方法 state = 1 の場合(区間が全てposで左揃え) ・区間が全てpi で左揃えされる場合:普通に更更新 ・区間が全てpi
で右揃えされる場合:普通に更更新 ・区間が揃わない場合: stateを -‐‑‒1 にして、左の⼦子に潜り、 ・左の⼦子が揃わなかった場合:右の⼦子には潜らない ・左の⼦子が揃った場合:右の⼦子にも潜る (state = 2 の場合(区間が全てposで右揃え)も同様) =state,posの組が同じ
更更新⽅方法 state = -‐‑‒1 の場合(区間が揃っていない) ・左の⼦子に潜る ・左の⼦子が揃わなかった場合:右の⼦子には潜らない
・左の⼦子が揃った場合:右の⼦子にも潜る ・潜った後、 ・左右の⼦子が揃った場合:state,posを⼦子と同じにする ・左右の⼦子が揃わなかった場合:stateを-‐‑‒1にする
更更新⽅方法 state = 1 の場合(区間が全てposで左揃え) ・区間が全てpi で左揃えされる場合:普通に更更新 ・区間が全てpi
で右揃えされる場合:普通に更更新 ・区間が揃わない場合: stateを -‐‑‒1 にして、左の⼦子に潜り、 ・左の⼦子が揃わなかった場合:右の⼦子には潜らない ・左の⼦子が揃った場合:右の⼦子にも潜る → ノードに w =「区間内の防壁の⻑⾧長さの最⼤大」も 持たせておくとよい(⻑⾧長いのが揃えば短いのも揃う)
答えを求める 答えを求めるためには、 各ノードになにを持たせればいいか
各移動の⻑⾧長さ 左揃え → 左揃え(右揃え → 右揃え) p 移動量量:pos -‐‑‒
p pos wi
左揃え → 右揃え(右揃え → 左揃え) pos wi 各移動の⻑⾧長さ 移動量量:p
-‐‑‒ pos -‐‑‒ wi + 1 p
答えを求める ・pos -‐‑‒ p ・p -‐‑‒ pos -‐‑‒ wi
+ 1 をいくつか⾜足したものが答え 各防壁の答えは、 ・x + wi * y という形で表せそう
答えを求める segtreeの各ノードに、sum,cnt という値を持たせる 答えは「sumの和 + cntの和 * wi 」
更更新は ・左揃え→左揃え:sum += pos -‐‑‒ p ・左揃え→右揃え:sum += p -‐‑‒ pos + 1, cnt -‐‑‒= wi とすればいい
まとめ segtreeを作り、ノードには以下の値を持たせる ・state,pos:左揃い・右揃い・不不揃い、揃った場所 ・w:防壁の最⼤大⻑⾧長区間(全て揃うかを判定するため) ・sum,cnt:答えを計算するための値 更更新は、
・state,posを更更新するついでにsum,cntを更更新する ・state=1,2(揃っている)なら普通に更更新 ・state=-‐‑‒1(不不揃い)なら⼦子に潜る → 計算量量は?
計算量量 state = -‐‑‒1 の場合(区間が揃っていない) ・左の⼦子に潜る ・左の⼦子が揃わなかった場合:右の⼦子には潜らない
・左の⼦子が揃った場合:右の⼦子にも潜る ・潜った後、 ・左右の⼦子が揃った場合:state,posを⼦子と同じにする ・左右の⼦子が揃わなかった場合:stateを-‐‑‒1にする state = 1 の場合(区間が全てposで左揃え) ・区間が全てp i で左揃えされる場合:普通に更更新 ・区間が全てp i で右揃えされる場合:普通に更更新 ・区間が揃わない場合: stateを -‐‑‒1 にして、左の⼦子に潜り、 ・左の⼦子が揃わなかった場合:右の⼦子には潜らない ・左の⼦子が揃った場合:右の⼦子にも潜る (state = 2 の場合(区間が全てposで右揃え)も同様) ポイント ・state = -‐‑‒1 なら潜る ・stateによらず、まず左の⼦子に潜り、 ・左の⼦子が揃わなかった場合:右の⼦子には潜らない ・左の⼦子が揃った場合:右の⼦子にも潜る
計算量量 ⾚赤い線のようにsegtree上を動きます たくさんのノードを辿ることもありそうに⾒見見えます
計算量量 ◯で囲ったような部分、 つまり左も右もがっつり潜る部分の個数を x とすると、 O(x * segtreeの⾼高さ(=logN))
で抑えられそうです ※ここのように、潜った直後に帰ってくる場所は含まない
計算量量 ・◯で囲ったような部分のstateは -‐‑‒1 のはず
計算量量 ・右の⼦子にも潜るということは、左の⼦子は全部揃っている → ◯の部分で右に潜ったということは、 △のstateが -‐‑‒1 から
1 か 2 になる
計算量量 つまり左も右もがっつり潜る部分の個数を x とすると、 O(x * segtreeの⾼高さ=(logN)) で抑えられそうです
・潜るノードの個数が O(log N) 回増えるときは、 state=-‐‑‒1 のノードが 1 つ減る! ・さらに、stateが 1 か 2 から -‐‑‒1 になるノードは、1つの レーザーにつき、O(log N) 個 → そのような場所は、 i = iより左は全部揃い、iより右は揃わない というような i を含む区間のみ
計算量量 ・潜るノードの個数が 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) になった!
⼩小課題2 このように、 保留留した頂点を後で潜る、遅延更更新の発展系のような⼿手法 を使うと、O(M log^2 N) で解けた!
参考 http://snuke.hatenablog.com/entry/2014/08/02/202210
⼩小課題3 初期位置がめちゃくちゃなので、そのままだとダメ 初期位置が 0 だったときとの差分を計算してやると良良い