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)); } }