ABC127 F - Absolute Minima
解法
は、とりあえず答えに加算すれば良いので、ほとんど無視して問題ないです。ということで、とについて考えていきます。
の総和を最小化する問題は、をの中央値にすればよいです。現在のがわかっているとき、となるようなについては、そうでないときはとなります。
中央値を計算する際、必要なのは中央値に近い部分のみです。ということで、より大きい部分と、そうでない部分で2つに分割し、ちょうど中間あたりのみを見ることができるようにします。
ここで登場するのが優先度付きキューです。2つ使用します。
について、値が小さいものについては降順に取り出すことができる優先度付きキューに、値が大きいものについては昇順に取り出すことができる別の優先度付きキューに格納すると、真ん中に近い部分が、2つのキューの先頭に現れます。
あとは、次に追加されると、2つのキューの先頭を見比べ、2つのキューが矛盾しないかつ、サイズの差が常に1以下になるように調整していけば、キューの先頭がちょうど中央値、になります。
の出力は、2つのキューの総和をあらかじめ求めておいて(キューの更新は要素を1つずつに対してのみなので、要素を入れたり出したりするたびに総和も更新しておけばよいです)、絶対値の計算の定義に合うように調整をします。小さい値が入っているキューの総和を-1倍すればよいです。その後、2つのキューの総和、の総和と、奇数の場合はを合わせて計算(小さいキューのサイズが大きい時はを加算、そうでないときは減算)すれば、答えが求まります。
感想
はじめ、BITでガリガリ計算しようと思っていたのですが、コンテスト後のTwitterでこの方法を聞き、天才だと思いました…
Fまでを全部解ききる力がまだ無いような気がします。