結果

問題 No.3198 Monotonic Query
ユーザー Nauclhlt🪷
提出日時 2025-07-03 21:07:31
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 174 ms / 3,000 ms
コード長 2,745 bytes
コンパイル時間 2,025 ms
コンパイル使用メモリ 198,660 KB
実行使用メモリ 7,844 KB
最終ジャッジ日時 2025-07-12 10:49:28
合計ジャッジ時間 6,989 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 22
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

template<typename T, T OP(T, T), T APPLY(T, T)>
class SegmentTree
{
private:
    int _treeSize;
    int _dataSize;
    int _originalDataSize;
    vector<T> _data;
    T _identity;

public:
    SegmentTree(int n, T identity)
    {
        _originalDataSize = n;
        _identity = identity;

        int size = 1;
        while (n > size)
        {
            size <<= 1;
        }

        _dataSize = size;
        _treeSize = 2 * size - 1;

        _data.resize(_treeSize, _identity);
    }

    int OriginalDataSize()
    {
        return _originalDataSize;
    }

    int TreeSize()
    {
        return _treeSize;
    }

    T Identity()
    {
        return _identity;
    }

    void Build(vector<T>& array)
    {
        if (_originalDataSize != (int)array.size())
        {
            throw exception();
        }

        for (int i = 0; i < (int)array.size(); i++)
        {
            _data[i + _dataSize - 1] = array[i];
        }

        for (int i = _dataSize - 2; i >= 0; i--)
        {
            _data[i] = OP(_data[(i << 1) + 1], _data[(i << 1) + 2]);
        }
    }

    void Apply(int index, T value)
    {
        index += _dataSize - 1;
        _data[index] = APPLY(_data[index], value);

        while (index > 0)
        {
            index = (index - 1) >> 1;
            _data[index] = OP(_data[(index << 1) + 1], _data[(index << 1) + 2]);
        }
    }

    T Query(int left, int right)
    {
        return QueryRec(left, right, 0, 0, _dataSize);
    }

    const T& operator[](size_t index) const
    {
        return _data[_dataSize - 1 + index];
    }

    T& operator[](size_t index)
    {
        return _data[_dataSize - 1 + index];
    }

private:
    T QueryRec(int left, int right, int index, int l, int r)
    {
        if (left >= r || right <= l)
        {
            return _identity;
        }

        if (left <= l && r <= right)
        {
            return _data[index];
        }

        return OP(QueryRec(left, right, (index << 1) + 1, l, (l + r) / 2), QueryRec(left, right, (index << 1) + 2, (l + r) / 2, r));
    }
};

ll op(ll a, ll b)
{
    return max(a, b);
}

ll apply(ll x, ll a)
{
    return a;
}
int main()
{
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int Q;
    cin >> Q;

    SegmentTree<ll, op, apply> seg(Q, 0LL);
    int last = 0;

    for (int i = 0; i < Q; i++)
    {
        int q;
        cin >> q;
        if (q == 1)
        {
            ll x;
            cin >> x;
            seg.Apply(last, x);
            last++;
        }
        else if (q == 2)
        {
            int k;
            cin >> k;
            cout << seg.Query(last - k, last) << endl;
        }
    }
}
0