AtCoder Beginner Contest 188 D – Snuke Prime を解いた記録

問題の概要

高橋くんは株式会社すぬけが提供しているサービス群を利用しようとしている.
株式会社すぬけは「すぬけプライム」なる支払いプランを用意しており,これを使うと\(1\)日\(C\)円ですべてのサービスを追加料金なしで利用できる.
すぬけプライムの加入及び脱退は,どちらも1日の初めまたは終わりに自由に行える.また,すぬけプライムの加入及び脱退は何回でもできる.

高橋くんは\(N\)個のサービスを利用しようとしている.
\(i\)個目のサービスは,\(a_{i}\)日目のはじめから\(b_{i}\)日目の終わりまで利用する予定である.
すぬけプライムに加入していない間は,\(i\)個目のサービスを利用するときに\(1\)日\(c_{i}\)円支払う必要がある.

サービスを利用するために高橋くんが支払う金額の最小値を求めよ.

問題へのリンク

制約

  • \(1 \leq N \leq 2 \times 10^{5}\)
  • \(1 \leq C \leq 10^{9}\)
  • \(1 \leq a_{i} \leq b_{i} \leq 10^{9}\)
  • \(1 \leq c_{i} \leq 10^{9}\)
  • 入力はすべて整数

解法

\(1 \leq a_{i} \leq b_{i} \leq 2 \times 10^{5}\)であればいもす法で一撃ですが,あいにく\(1 \leq a_{i} \leq b_{i} \leq 10^{9}\)となっているためいもす法をそのまま使うことはできません.
しかし,いもす法で使う配列を連想配列(C++ならstd::map)に置き換えれば,いもす法の要領で答えにたどり着けます.

具体的には,連想配列\(memo\)に対して

  • \(memo[a_{i}] += c_{i}\)
  • \(memo[b_{i}+1] -= c_{i}\)

とする処理をすべての\(i\)について行い,\(memo\)を先頭から順に確認して料金計算を行えばよいです.

実装例

感想

当初はmapに要素を追加するときの場合分け(\(a_{i}\)などをキーとする要素が連想配列にあるか否かで処理を分ける)をしていましたが,場合分けしているコードを投げている間はずっとWAが出ていました.
コンテスト中はPythonで無理やりACしましたが,4回もWAを出したせいもあってパフォーマンスがかなぐり犠牲になりました.かなしい