tookunn’s diary

主に競技プログラミング関係

AtCoder Beginner Contest 188 D - Snuke Prime

問題

atcoder.jp

考察

1 \le a_i \le b_i \le 10^9となっていて、区間として範囲が大きいので
いもす法という手法を使って、単純に各区間の増減の累積和を取ることができないことが分かる。

最初は各区間について a_i, b_iを一組としてまとめて、うまくソートなりなんなりをすれば良さそうと考えていたが
そこからまったく分からなかった。

公式解説によると
区間 a_i, b_iをまとめて考えるのではなく、 a_i, b_iを別々のものとして扱い、
いもす法の発想を少し応用した工夫をすることで解くことができる。

f:id:tookunn:20210503192521p:plain

こんな感じに区間を直線で表すと
 i日目を1からなめていったときにいずれかの区間 a_i b_iと重なるまで
払う料金は一定で、 a_i b_iに出くわしたときに料金が変動することが分かるので
いもす法っぽく a_i日目に +c_i円、 b_i + 1日目に - c_i円という料金が変動する情報を持っておけば良い。

あとは料金が変動する情報を日にちの昇順になめていって、 min(変動前の料金, C) \times 日数で料金を計算していけば良い。

ソースコード

キーでforループを回したときに順序を持たせる必要があったので、MapはHashMapではなくTreeMapにした。
よく分からないが、HashMapだとキーの一意性をハッシュで管理しているため、キーの順序は考慮されないっぽい。
atcoder.jp