問題はこちら
問題概要
東西に無限に続く1本の大通りがあり, 数直線とみなすことができる. 回道路工事が行われる. 番目の道路工事は時刻から時刻まで座標を通行止めにする. 人の人が座標0に立っている. 番目の人は時刻に座標0を出発し, 速度1で正の方向へ歩き続ける. 歩いている途中で通行止めとなっている地点に到達した場合には, そこで歩くのをやめる. 人がそれぞれが進む距離を求めよ.
思考の流れ(自分の解法)
時刻に座標0を出発した人が時刻からの間に座標に到達する条件は,
各道路工事に対してとを求めておくことで, 各人に対して条件を満たす道路工事のなかでXが最小のものを答えればよい. しかしこのままでは計算量はとなる.
ここで, 番目の要素が「時刻に座標0を出発した人が止まる座標」とする配列を作る. 作り方は, 配列の各要素をに初期化しておき, 各道路工事に対してから番目の要素にを書いていけばよい. 範囲が重なる場合はが小さい方を書く必要があるのでが大きい順に更新していけばいい.
しかし, これだと配列の要素が最大で必要になるし, 更新にも時間がかかる.
これは, 使う座標のみを残した座標圧縮を行えばよい. 使う座標はである. 更新は遅延評価ができるSegmentTreeなどを用いて更新していけばよい.
思考の流れ(公式解説動画の解法)
setに人の出発時刻を入れて, の小さい方から処理していく. 以上のものをset上で二分探索して以下のものをsetから除いていく. の小さい方から処理しているので, 取り除いかれた時のの値がその人の止まる位置となる. 二分探索や挿入, 削除にかかる. 取り除かれなかったものは, 取り除かれる範囲に無いということなので
思考の流れ(公式解説pdfの解法)
イベントソートというらしい. 今度はsetに工事の情報を入れる. setには常に現在行われている工事(からと考える)の座標が入っているようにする. 現在の時刻を進めていき, 工事の開始時刻にsetにを入れ, 工事の終了時刻にを取り除く. これの実現方法は, まずとを各工事ごとに配列に入れソートする. そして, 人の座標0の出発時刻に出発時刻以前の動作(setへの追加,削除)を行う. ならば, をsetに追加し, ならばをsetから削除する. 各人について動作を行った後の止まる位置はsetにある最小値となる. setに何もない場合は.
提出プログラム
https://atcoder.jp/contests/abc128/submissions/12246363 https://atcoder.jp/contests/abc128/submissions/12255174 https://atcoder.jp/contests/abc128/submissions/12255873
感想
無理やりゴリおした感あった. 公式解説pdfの解法はいろいろなところで使えそうなので覚えておきたい.