結果
問題 |
No.3298 K-th Slime
|
ユーザー |
|
提出日時 | 2025-10-05 14:33:25 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 180 ms / 2,000 ms |
コード長 | 18,616 bytes |
コンパイル時間 | 5,423 ms |
コンパイル使用メモリ | 334,524 KB |
実行使用メモリ | 11,520 KB |
最終ジャッジ日時 | 2025-10-05 14:33:40 |
合計ジャッジ時間 | 7,893 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 25 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using ll = long long; using lll = __int128_t; #define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i) #define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i) #define rrep(i, n) for (int i = ((int)(n) - 1); i >= 0; --i) #define rreps(i, n) for (int i = ((int)(n)); i > 0; --i) #define rep2(i, s, n) for (int i = (s); i < (int)(n); i++) #define repc2(i, s, n) for (int i = (s); i <= (int)(n); i++) #define length(v) ((int)(v).size()) constexpr int inf = 2'000'000'000; constexpr ll linf = 4'000'000'000'000'000'000, M7 = 1'000'000'007, M9 = 998'244'353; #define all(v) begin(v), end(v) #define rall(v) rbegin(v), rend(v) using namespace std; using namespace atcoder; // clang-format off using vint = vector<int>;using vvint = vector<vector<int>>;using vvvint = vector<vector<vector<int>>>; using vll = vector<ll>;using vvll = vector<vector<ll>>;using vvvll = vector<vector<vector<ll>>>; using vlll = vector<lll>;using vvlll = vector<vector<lll>>;using vvvlll = vector<vector<vector<lll>>>; using vchar = vector<char>;using vvchar = vector<vector<char>>;using vvvchar = vector<vector<vector<char>>>; using vstr = vector<string>;using vvstr = vector<vector<string>>;using vvvstr = vector<vector<vector<string>>>; using vpi = vector<pair<int, int>>;using vvpi = vector<vector<pair<int, int>>>;using vvpint = vector<vector<pair<int, int>>>; using vpl = vector<pair<ll, ll>>;using vvpl = vector<vector<pair<ll, ll>>>;using vvplint = vector<vector<pair<ll, int>>>; using vbool = vector<bool>;using vvbool = vector<vector<bool>>;using vvvbool = vector<vector<vector<bool>>>; #define Vec(type, ...) __make_vec<type>(__VA_ARGS__) template <class T> vector<T> __make_vec(size_t a) {return vector<T>(a);}template <class T, class... Ts> auto __make_vec(size_t a, Ts... ts) {return vector<decltype(__make_vec<T>(ts...))>(a, __make_vec<T>(ts...));} #define VecI(init, type, ...) __make_vecI<type, init>(__VA_ARGS__) template <class T, T init>vector<T> __make_vecI(size_t a) {return vector<T>(a, init);} template <class T, T init, class... Ts> auto __make_vecI(size_t a, Ts... ts) {return vector<decltype(__make_vecI<T, init>(ts...))>(a, __make_vecI<T, init>(ts...));} template <typename T, typename U>inline ostream& operator<<(ostream& os, const pair<T, U>& p) noexcept {return os << p.first << " " << p.second;} inline ostream& operator<<(ostream& os, const modint& m) noexcept { return os << m.val(); } template <int M>inline ostream& operator<<(ostream& os, const static_modint<M>& m) noexcept { return os << m.val(); } template <typename T> struct is_static_modint : std::false_type {}; template <int MOD> struct is_static_modint<static_modint<MOD>> : std::true_type {}; template <template <typename...> typename C, typename Number>concept MyContainer = std::is_same_v<C<Number>, std::vector<Number>> || std::is_same_v<C<Number>, std::deque<Number>> || std::is_same_v<C<Number>, std::set<Number>> || std::is_same_v<C<Number>, std::unordered_set<Number>> || std::is_same_v<C<Number>, std::unordered_multiset<Number>> || std::is_same_v<C<Number>, std::multiset<Number>>; template <typename Number>concept MyNumber = std::is_same_v<Number, int> || std::is_same_v<Number, ll> || std::is_same_v<Number, char> || std::is_same_v<Number, modint> || is_static_modint<Number>::value; template <template <typename...> typename C, typename Number>concept MyContainerNumber = MyContainer<C, Number> && MyNumber<Number>; template <template <typename...> typename OutCon, template <typename...> typename InCon, typename Number>concept MyNestedContainerNumber = MyContainer<OutCon, InCon<Number>> && MyContainerNumber<InCon, Number>; template <template <typename...> typename C, typename Number>requires MyContainerNumber<C, Number>std::ostream& operator<<(std::ostream& os, const C<Number>& t) {auto itr = t.begin();auto end = t.end();if (itr != end) {os << *itr++;for (; itr != end; ++itr) os << ' ' << *itr;}return os;} template <template <typename...> typename OutCon, template <typename...> typename InCon, typename Number>requires MyNestedContainerNumber<OutCon, InCon, Number>std::ostream& operator<<(std::ostream& os, const OutCon<InCon<Number>>& t) {auto itr = t.begin();auto end = t.end();if (itr != end) {os << *itr++;for (; itr != end; ++itr) os << '\n' << *itr;}return os;} template <typename T, typename U>istream& operator>>(istream& is, pair<T, U>& p) {return is >> p.first >> p.second;} template <typename T>istream& operator>>(istream& is, vector<T>& v) {for (auto& e : v) is >> e;return is;} void inp() {} template <typename T, typename... Args>void inp(T& a, Args&... args) {cin >> a, inp(args...);} template <typename T>void inp1(vector<T>& v, int offset = 1, int len = -1) {if (len == -1) len = int(v.size()) - offset;assert(offset >= 0 && len >= 0);for (int i = offset; i < offset + len; ++i) cin >> v[i];} template <typename T>void oup(const T& a) {cout << a << "\n";} template <typename T, typename... Args>void oup(const T& a, const Args&... args) {cout << a << " ", oup(args...);} inline string YesNo(bool cond) { return cond ? "Yes" : "No"; } inline auto add1(auto vec, ll offset = 1) {for (auto& e : vec) e += offset;return vec;} #ifdef ONLINE_JUDGE #define debug(...) #else #define debug(...) cerr << "<" << #__VA_ARGS__ << ">: ", debug_out(__VA_ARGS__) template <typename T>void debug_out(T t) {cerr << t << "\n";} template <typename T, typename... Args>void debug_out(T t, Args... args) {cerr << t << ", ";debug_out(args...);} #endif #ifdef ONLINE_JUDGE #define todo(...) static_assert(false) #else #define todo(...) #endif // clang-format on template <class S, S (*op)(S, S), S (*e)(), bool COMMUTATIVE, S (*reverse_prod)(S), bool LAZY, class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()> struct LazyLazyTreap { static_assert((LAZY && !std::is_same_v<F, std::nullptr_t>) || (!LAZY && std::is_same_v<F, std::nullptr_t>), "F must be nullptr_t if LAZY is false"); private: template <typename U, typename = void> struct has_fail_member : std::false_type {}; template <typename U> struct has_fail_member<U, std::void_t<decltype(std::declval<U>().fail)>> : std::true_type {}; static constexpr bool beats = has_fail_member<S>::value; static_assert(!beats || LAZY, "beats! requires LAZY"); template <class FF, nullptr_t Dummy = nullptr> struct _Node { _Node *l, *r; uint32_t pri; int size; bool rev; S val, prod; FF lazy; bool is_id; }; template <nullptr_t Dummy> struct _Node<void, Dummy> { _Node *l, *r; uint32_t pri; int size; bool rev; S val, prod; }; using Node = std::conditional_t<LAZY, _Node<F>, _Node<void>>; static Node* _alloc(Node* t = nullptr) { static std::deque<Node> pool; static std::vector<Node*> pool_used; if (t != nullptr) { pool_used.emplace_back(t); return t; } if (pool_used.empty()) { pool.emplace_back(); return &pool.back(); } Node* ptr = pool_used.back(); pool_used.pop_back(); return ptr; } static void _delete_node(Node* t) { _alloc(t); } Node* _new_node(S val) { Node* ptr = _alloc(); static mt19937 mt(std::random_device{}()); if constexpr (LAZY) { *ptr = {nullptr, nullptr, uint32_t(mt()), 1, false, val, val, id(), true}; } else { *ptr = {nullptr, nullptr, uint32_t(mt()), 1, false, val, val}; } return ptr; } int _size(Node* t) const { return t != nullptr ? t->size : 0; } void _all_apply(Node* t, F f) { if (t == nullptr) return; t->val = mapping(f, t->val); t->prod = mapping(f, t->prod); t->lazy = composition(f, t->lazy); t->is_id = false; if (t->l || t->r) { if constexpr (beats) { if (t->prod.fail) _push(t), _update(t); } } } void _push(Node* t) { if (t == nullptr) return; if constexpr (LAZY) { if (!t->is_id) { if (t->l != nullptr) _all_apply(t->l, t->lazy); if (t->r != nullptr) _all_apply(t->r, t->lazy); t->lazy = id(); t->is_id = true; } } if (t->rev) { std::swap(t->l, t->r); if (t->l != nullptr) { t->l->rev ^= 1; if constexpr (!COMMUTATIVE) t->l->val = reverse_prod(t->l->val); } if (t->r != nullptr) { t->r->rev ^= 1; if constexpr (!COMMUTATIVE) t->r->val = reverse_prod(t->r->val); } t->rev = false; } } void _update(Node* t) { t->size = _size(t->l) + _size(t->r) + 1; t->prod = t->val; if (t->l != nullptr) t->prod = op(t->l->prod, t->prod); if (t->r != nullptr) t->prod = op(t->prod, t->r->prod); } Node* _merge(Node* l, Node* r) { if (l == nullptr) return r; if (r == nullptr) return l; if (l->pri > r->pri) { _push(l); l->r = _merge(l->r, r); _update(l); return l; } else { _push(r); r->l = _merge(l, r->l); _update(r); return r; } } pair<Node*, Node*> _split(Node* t, int k) { if (t == nullptr) return {nullptr, nullptr}; if (k == 0) return {nullptr, t}; if (k == _size(t)) return {t, nullptr}; _push(t); if (k <= _size(t->l)) { auto [l, r] = _split(t->l, k); t->l = r; _update(t); return {l, t}; } else { auto [l, r] = _split(t->r, k - _size(t->l) - 1); t->r = l; _update(t); return {t, r}; } } Node* _insert(Node* t, int k, S val) { auto x = _split(t, k); return _merge(_merge(x.first, _new_node(val)), x.second); } Node* _erase(Node* t, int k) { auto x = _split(t, k); auto y = _split(x.second, 1); _delete_node(y.first); return _merge(x.first, y.second); } Node* _apply(Node* t, const F& f, int l, int r) { auto [a, b] = _split(t, l); auto [c, d] = _split(b, r - l); _all_apply(c, f); return _merge(a, _merge(c, d)); } S _prod(Node*& t, int l, int r) { auto [a, b] = _split(t, l); auto [c, d] = _split(b, r - l); _push(c); S res = c->prod; t = _merge(a, _merge(c, d)); return res; } Node* _reverse(Node* t, int l, int r) { auto [a, b] = _split(t, l); auto [c, d] = _split(b, r - l); c->rev ^= 1; if constexpr (!COMMUTATIVE) c->val = reverse_prod(c->val); return _merge(_merge(a, c), d); } Node* _build(int l, int r, const std::vector<S>& v) { if (l + 1 >= r) return _new_node(v[l]); int mid = (l + r) / 2; return _merge(_build(l, mid, v), _build(mid, r, v)); } void _set(Node* t, int k, const S& val) { if (t == nullptr) return; _push(t); if (k < _size(t->l)) { _set(t->l, k, val); } else if (k == _size(t->l)) { t->val = val; } else { _set(t->r, k - _size(t->l) - 1, val); } _update(t); } S _get(Node* t, int k) { if (t == nullptr) return e(); _push(t); if (k < _size(t->l)) { return _get(t->l, k); } else if (k == _size(t->l)) { return t->val; } else { return _get(t->r, k - _size(t->l) - 1); } } std::string _to_string(Node* t) { std::stringstream ss; int cnt = _size(t); std::function<void(Node*)> dfs = [&](Node* t) { if (t == nullptr) return; _push(t); dfs(t->l); ss << t->val; if (--cnt) ss << " "; dfs(t->r); }; dfs(t); return ss.str(); } pair<S, int> _max_right_sub(Node* p, int nl, int nr, S left, function<bool(S)> f) { _push(p); S nxt = op(left, p->prod); if (f(nxt)) { return {nxt, nr}; } else if (p->l == nullptr && p->r == nullptr) { return {left, nl}; } int lsz = _size(p->l); if (p->l) { auto [left_res, left_idx] = _max_right_sub(p->l, nl, nl + lsz, left, f); if (left_idx != nl + lsz) return {left_res, left_idx}; left = left_res; } S nxtt = op(left, p->val); if (!f(nxtt)) return {left, nl + lsz}; if (p->r) return _max_right_sub(p->r, nl + lsz + 1, nr, nxtt, f); assert(false); } pair<S, int> _min_left_sub(Node* p, int nl, int nr, S right, function<bool(S)> f) { _push(p); S nxt = op(p->prod, right); if (f(nxt)) { return {nxt, nl}; } else if (p->l == nullptr && p->r == nullptr) { return {right, nr}; } int rsz = _size(p->r); if (p->r) { auto [right_res, right_idx] = _min_left_sub(p->r, nr - rsz, nr, right, f); if (right_idx != nr - rsz) return {right_res, right_idx}; right = right_res; } S nxtt = op(p->val, right); if (!f(nxtt)) return {right, nr - rsz}; if (p->l) return _min_left_sub(p->l, nl, nr - rsz - 1, nxtt, f); assert(false); } Node* root; LazyLazyTreap(Node* t) : root(t) {} public: LazyLazyTreap() : root(nullptr) {} LazyLazyTreap(const std::vector<S>& v) : root(_build(0, v.size(), v)) {} LazyLazyTreap(const LazyLazyTreap& t) : root(t.root) { std::vector<S> v; auto dfs = [&](auto dfs, Node* t) -> void { if (t == nullptr) return; _push(t); dfs(dfs, t->l); v.push_back(t->val); dfs(dfs, t->r); }; dfs(dfs, root); root = _build(0, v.size(), v); } LazyLazyTreap(LazyLazyTreap&& t) : root(t.root) { t.root = nullptr; } void merge(LazyLazyTreap& t) { root = _merge(root, t.root); } std::pair<LazyLazyTreap, LazyLazyTreap> split(int k) { auto [l, r] = _split(root, k); root = nullptr; return {LazyLazyTreap(l), LazyLazyTreap(r)}; } void insert(int k, S val) { assert(0 <= k && k <= _size(root)); root = _insert(root, k, val); } void erase(int k) { assert(0 <= k && k < _size(root)); root = _erase(root, k); } S prod(int l, int r) { assert(0 <= l && l <= r && r <= _size(root)); if (l == r) return e(); return _prod(root, l, r); } void apply(int l, int r, const F& f) { assert(0 <= l && l <= r && r <= _size(root)); static_assert(LAZY); if (l == r) return; root = _apply(root, f, l, r); } void reverse(int l, int r) { assert(0 <= l && l <= r && r <= _size(root)); if (l == r) return; root = _reverse(root, l, r); } void set(int k, S val) { assert(0 <= k && k < _size(root)); _set(root, k, val); } S get(int k) { assert(0 <= k && k < _size(root)); return _get(root, k); } int size() const { return _size(root); } bool empty() const { return root == nullptr; } friend std::ostream& operator<<(std::ostream& os, LazyLazyTreap& tr) { os << tr._to_string(tr.root); return os; } void push_back(S val) { root = _merge(root, _new_node(val)); } void pop_back() { assert(_size(root)); root = _erase(root, _size(root) - 1); } void push_front(S val) { root = _merge(_new_node(val), root); } void pop_front() { assert(_size(root)); root = _erase(root, 0); } int max_right(int l, function<bool(S)> f) { int n = _size(root); assert(0 <= l && l <= n); assert(f(e())); if (l == n) return n; auto [x, y] = _split(root, l); int res = _max_right_sub(y, 0, n - l, e(), f).second + l; root = _merge(x, y); return res; } int min_left(int r, function<bool(S)> f) { int n = _size(root); assert(0 <= r && r <= n); assert(f(e())); if (r == 0) return 0; auto [x, y] = _split(root, r); int res = _min_left_sub(x, 0, r, e(), f).second; root = _merge(x, y); return res; } bool is_beats() const { return beats; } LazyLazyTreap& operator+(LazyLazyTreap& t) { merge(t); return *this; } LazyLazyTreap& operator=(LazyLazyTreap& t) { root = t.root; t.root = nullptr; return *this; } }; template <typename S> static S dummy_reverse_prod(S s) { return s; } template <typename S> static S dummy_mapping(nullptr_t f, S s) { return s; } static nullptr_t dummy_composition(nullptr_t f, nullptr_t g) { return f; } static nullptr_t dummy_id() { return nullptr; } template <class S, S (*op)(S, S), S (*e)(), bool COMMUTATIVE = true, S (*reverse_prod)(S) = dummy_reverse_prod> using Treap = LazyLazyTreap<S, op, e, COMMUTATIVE, reverse_prod, false, nullptr_t, dummy_mapping, dummy_composition, dummy_id>; template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)(), bool COMMUTATIVE = true, S (*reverse_prod)(S) = dummy_reverse_prod> using LazyTreap = LazyLazyTreap<S, op, e, COMMUTATIVE, reverse_prod, true, F, mapping, composition, id>; ll op(ll x, ll y) { return max(x, y); } ll e() { return -linf; } #pragma GCC diagnostic push #pragma GCC diagnostic error "-Wshadow" int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); ll n, k, q; inp(n, k, q); vll a(n); inp(a); sort(all(a)); Treap<ll, op, e> tr; rep(i, n) tr.push_back(a[i]); auto insert = [&](ll x) -> void { int idx = tr.max_right(0, [&](auto y) { return x >= y; }); // debug(x, idx); debug(idx, x, tr); tr.insert(idx, x); }; rep(i, q) { ll c; inp(c); debug(tr); if (c == 1) { ll x; inp(x); insert(x); } else if (c == 2) { ll y; inp(y); ll z = tr.get(k - 1); tr.erase(k - 1); insert(z + y); } else { oup(tr.get(k - 1)); } } } #pragma GCC diagnostic pop