結果
問題 |
No.3017 交互浴
|
ユーザー |
|
提出日時 | 2025-01-31 19:20:38 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 160 ms / 2,000 ms |
コード長 | 1,430 bytes |
コンパイル時間 | 4,219 ms |
コンパイル使用メモリ | 203,648 KB |
実行使用メモリ | 13,656 KB |
最終ジャッジ日時 | 2025-01-31 19:20:59 |
合計ジャッジ時間 | 18,536 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 55 |
ソースコード
import std; void main () { int N = readln.chomp.to!int; auto H = readln.split.to!(int[]); // 区切り線に着目。 // 区切り線は新しく追加と削除のO(1)回までしか操作を受けないので、温泉で上書きされるときは全部見ていい。 // あとは今最下層が何色かわかれば変化分がわかる。 // となると、最小値取得と挿入ができればok。 auto pq = BinaryHeap!(int[], "b < a")([]); int v = 0; auto ans = new int[](N); foreach (i; 0 .. N) { int pre = 0; int c = i % 2; while (!pq.empty() && pq.front() <= H[i]) { if (c == 1) { v -= pq.front() - pre; } pre = pq.front(); pq.removeFront(); c ^= 1; } // 上がいればその分も削除 if (!pq.empty()) { if (c == 1) { v -= H[i] - pre; } } // 色が異なっていれば境目を挿入 if (c != (i + 1) % 2) { pq.insert(H[i]); } if ((i + 1) % 2 == 1) { v += H[i]; } ans[i] = v; } writefln("%(%s\n%)", ans); } void read (T...) (string S, ref T args) { import std.conv : to; import std.array : split; auto buf = S.split; foreach (i, ref arg; args) { arg = buf[i].to!(typeof(arg)); } }