結果

問題 No.3017 交互浴
コンテスト
ユーザー iastm
提出日時 2025-12-07 03:38:22
言語 C++23
(gcc 13.3.0 + boost 1.89.0)
結果
AC  
実行時間 468 ms / 2,000 ms
コード長 3,214 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 1,198 ms
コンパイル使用メモリ 103,884 KB
実行使用メモリ 7,852 KB
最終ジャッジ日時 2025-12-07 03:38:54
合計ジャッジ時間 31,212 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 55
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <iostream>
// #include <kotone/interval_set>
// https://github.com/amiast/cpp-utility

#ifndef KOTONE_INTERVAL_SET_HPP
#define KOTONE_INTERVAL_SET_HPP 1

#include <vector>
#include <set>
#include <cassert>

namespace kotone {

// A data structure that manages non-overlapping intervals.
template <typename T> struct interval_set {
    using interval = std::pair<T, T>;

  private:
    std::set<interval> _set;
    T _length{};

  public:
    // Constructs an empty interval set.
    interval_set() noexcept {}

    // Returns the number of disconnected intervals in the set.
    int num_intervals() const noexcept {
        return _set.size();
    }

    // Returns the sum of lengths of intervals in the set.
    T length() const noexcept {
        return _length;
    }

    // Inserts the interval `[l, r)` into the set.
    // Requires `l <= r`.
    void insert(T l, T r) {
        assert(l <= r);
        if (l == r) return;
        auto iter = _set.lower_bound({l, l});
        if (iter != _set.begin()) {
            auto prev = std::prev(iter);
            if (prev->second >= r) return;
            if (prev->second >= l) {
                _length -= prev->second - prev->first;
                l = prev->first;
                _set.erase(prev);
            }
        }
        while (iter != _set.end() && iter->first <= r) {
            _length -= iter->second - iter->first;
            if (iter->second > r) r = iter->second;
            iter = _set.erase(iter);
        }
        _length += r - l;
        _set.emplace(l, r);
    }

    // Removes intervals in the range `[l, r)` and returns a vector containing the removed intervals.
    // Requires `l <= r`.
    std::vector<interval> remove(T l, T r) {
        assert(l <= r);
        if (l == r) return {};
        std::vector<interval> result;
        auto iter = _set.lower_bound({l, l});
        if (iter != _set.begin()) {
            auto prev = std::prev(iter);
            if (prev->second > r) {
                _length -= r - l;
                _set.emplace(prev->first, l);
                _set.emplace(r, prev->second);
                _set.erase(prev);
                return {{l, r}};
            }
            if (prev->second > l) {
                _length -= prev->second - l;
                _set.emplace(prev->first, l);
                result.emplace_back(l, prev->second);
                _set.erase(prev);
            }
        }
        while (iter != _set.end() && iter->first < r) {
            if (iter->second > r) {
                _length -= r - iter->first;
                _set.emplace(r, iter->second);
                result.emplace_back(iter->first, r);
            } else {
                _length -= iter->second - iter->first;
                result.push_back(*iter);
            }
            iter = _set.erase(iter);
        }
        return result;
    }
};

}  // namespace kotone

#endif  // KOTONE_INTERVAL_SET_HPP

int main() {
    int N;
    std::cin >> N;
    kotone::interval_set<int> set;
    for (int i = 0; i < N; i++) {
        int h;
        std::cin >> h;
        if (i % 2 == 0) set.insert(0, h);
        else set.remove(0, h);
        std::cout << set.length() << std::endl;
    }
}
0