AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。
出典:
AtCoder Beginner Contest 127 D – Integer Cards
問題を読んで最初に思いついたのは、優先度付きキューを用いたシミュレートだったが、制約が 1 \le N \le 10^5, 1 \le M \le 10^5 で、最悪 NM 回行うことを考えると間に合わなさそう。なので、真面目に考察を行う必要がある。
カードに書かれた数字を書き換えると考えると一見面倒くさそうだが、新たにカードを引き、その際に一番数字の小さいカードを捨てる、と考えると見通しが立てやすいかも。
def main():
N, M = map(int, input().split())
A = list(map(int, input().split()))
changes = [list(map(int, input().split())) for _ in range(M)]
cnt = dict()
for a in A:
if a not in cnt:
cnt[a] = 0
cnt[a] += 1
for b, c in changes:
if c not in cnt:
cnt[c] = 0
cnt[c] += b
cards = list(cnt.keys())
cards.sort(reverse=True)
taken = 0
result = 0
for card in cards:
n = cnt[card]
if taken + n < N:
result += card * n
taken += n
else:
n = N - taken
result += card * n
break
print(result)
main()
関連