#include using namespace std; using ll = long long; #ifdef LOCAL #include #else #define debug(...) #endif // https://codeforces.com/contest/1638/problem/E // 持つ値のタイプ T、座標タイプ X // コンストラクタでは T none_val を指定する template struct Intervals { static constexpr X LLIM = numeric_limits::lowest(); static constexpr X RLIM = numeric_limits::max(); T none_val; // const T none_val; // none_val でない区間の個数と長さ合計 int total_num; X total_len; map dat; Intervals(T none_val) : none_val(none_val), total_num(0), total_len(0) { dat[LLIM] = none_val; dat[RLIM] = none_val; } // x を含む区間の情報の取得 l, r, t tuple get(X x, bool ERASE = false) { auto it2 = dat.upper_bound(x); auto it1 = prev(it2); auto [l, tl] = *it1; auto [r, tr] = *it2; if (tl != none_val && ERASE) { --total_num, total_len -= r - l; dat[l] = none_val; merge_at(l); merge_at(r); } return {l, r, tl}; } // [L, R) 内の全データの取得 f(l, r, t) template void enumerate_range(X L, X R, F f, bool ERASE = false) { assert(LLIM <= L && L <= R && R <= RLIM); if (!ERASE) { auto it = prev(dat.upper_bound(L)); while ((*it).first < R) { auto it2 = next(it); f(max((*it).first, L), min((*it2).first, R), (*it).second); it = it2; } return; } // 半端なところの分割 auto p = prev(dat.upper_bound(L)); if ((*p).first < L) { dat[L] = (*p).second; if (dat[L] != none_val) ++total_num; } p = dat.lower_bound(R); if (R < (*p).first) { T t = (*prev(p)).second; dat[R] = t; if (t != none_val) ++total_num; } p = dat.lower_bound(L); while (1) { if ((*p).first >= R) break; auto q = next(p); T t = (*p).second; f((*p).first, (*q).first, t); if (t != none_val) --total_num, total_len -= (*q).first - (*p).first; p = dat.erase(p); } dat[L] = none_val; } void set(X L, X R, T t) { assert(L <= R); if (L == R) return; enumerate_range(L, R, [](int l, int r, T x) -> void {}, true); dat[L] = t; if (t != none_val) total_num++, total_len += R - L; merge_at(L); merge_at(R); } template void enumerate_all(F f) { enumerate_range(LLIM, RLIM, f, false); } void merge_at(X p) { if (p == LLIM || RLIM == p) return; auto itp = dat.lower_bound(p); assert((*itp).first == p); auto itq = prev(itp); if ((*itp).second == (*itq).second) { if ((*itp).second != none_val) --total_num; dat.erase(itp); } } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int N; cin >> N; vector H(N); for (int i = 0; i < N; i++) cin >> H[i]; Intervals I(0); for (int i = 0; i < N; i++) { if (i & 1) { I.set(0, H[i], 0); // 緑 } else { I.set(0, H[i], 1); // 水色 } cout << I.total_len << "\n"; } }