#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1508" #include <iostream> #include "Mylib/AlgebraicStructure/Monoid/min.cpp" #include "Mylib/DataStructure/BBST/treap.cpp" #include "Mylib/IO/input_tuples.cpp" #include "Mylib/IO/input_tuples_with_index.cpp" namespace hl = haar_lib; int main() { int n, q; std::cin >> n >> q; hl::treap<hl::min_monoid<int>> s(n); for (auto [i, a] : hl::input_tuples_with_index<int>(n)) { s.set(i, {a}); } for (auto [x, y, z] : hl::input_tuples<int, int, int>(q)) { if (x == 0) { auto temp = s.get(z).value(); s.erase(z); s.insert(y, {temp}); } else if (x == 1) { auto ans = s.fold(y, z + 1).value(); std::cout << ans << std::endl; } else { s.set(y, z); } } return 0; }
#line 1 "test/aoj/1508/main.treap.test.cpp" #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1508" #include <iostream> #line 2 "Mylib/AlgebraicStructure/Monoid/min.cpp" #include <algorithm> #include <optional> namespace haar_lib { template <typename T> struct min_monoid { using value_type = std::optional<T>; value_type operator()() const { return {}; } value_type operator()(const value_type &a, const value_type &b) const { if (not a) return b; if (not b) return a; return {std::min(*a, *b)}; } }; } // namespace haar_lib #line 2 "Mylib/DataStructure/BBST/treap.cpp" #include <random> #include <tuple> #include <utility> namespace haar_lib { template <typename Monoid> struct treap_node { using node = treap_node<Monoid>; using value_type = typename Monoid::value_type; const static Monoid M; static std::mt19937 rand; value_type value, result; node *left = nullptr, *right = nullptr; int priority, size = 1; bool rev = false; treap_node() : priority(rand()) {} treap_node(const value_type &value) : value(value), result(value), priority(rand()) {} static int count(node *t) { return t ? t->size : 0; } static value_type sum(node *t) { return t ? t->result : M(); } static node *update_node_status(node *t) { t->size = count(t->right) + count(t->left) + 1; t->result = M(M(sum(t->right), sum(t->left)), t->value); return t; } static void pushdown(node *t) { if (not t) return; if (t->rev) { std::swap(t->left, t->right); if (t->left) t->left->rev ^= true; if (t->right) t->right->rev ^= true; t->rev = false; } update_node_status(t); } static node *insert(node *t, int k, const value_type &val) { auto s = split(t, k); return merge(s.first, merge(new node(val), s.second)); } static node *erase(node *t, int k) { node *l, *r, *m; std::tie(l, r) = split(t, k); std::tie(m, r) = split(r, 1); return merge(l, r); } static std::pair<node *, node *> split(node *t, int k) { if (not t) return std::make_pair(nullptr, nullptr); pushdown(t); const int c = count(t->left); if (k <= c) { auto s = split(t->left, k); t->left = s.second; return std::make_pair(s.first, update_node_status(t)); } else { auto s = split(t->right, k - (c + 1)); t->right = s.first; return std::make_pair(update_node_status(t), s.second); } } static node *merge(node *l, node *r) { pushdown(l); pushdown(r); if (not l or not r) return l ? l : r; if (l->priority > r->priority) { l->right = merge(l->right, r); return update_node_status(l); } else { r->left = merge(l, r->left); return update_node_status(r); } } static node *reverse(node *t, int l, int r) { node *a, *b, *c; std::tie(a, c) = split(t, l); std::tie(b, c) = split(c, r - l); b->rev ^= true; return t = merge(merge(a, b), c); } static void update_node(node *t, int k, const value_type &value) { const int c = count(t->left); if (k == c) t->value = value; else if (k > c) update_node(t->right, k - (c + 1), value); else update_node(t->left, k, value); update_node_status(t); } static node *get_node(node *t, int k) { if (not t) return t; pushdown(t); int c = count(t->left); if (k == c) return t; if (k > c) return get_node(t->right, k - (c + 1)); else return get_node(t->left, k); } template <typename Func> static void traverse(node *t, const Func &f) { if (t) { pushdown(t); traverse(t->left, f); f(*t); traverse(t->right, f); } } }; template <typename Monoid> std::mt19937 treap_node<Monoid>::rand; template <typename Monoid> class treap { public: using value_type = typename Monoid::value_type; protected: using node = treap_node<Monoid>; Monoid M_; node *root_ = nullptr; treap(node *t) : root_(t) {} public: treap() {} treap(int n) { for (int i = 0; i < n; ++i) push_back(M_()); } int size() const { return node::count(root_); } bool empty() const { return not root_; } void insert(int k, const value_type &val) { root_ = node::insert(root_, k, val); } void erase(int k) { root_ = node::erase(root_, k); } void merge_left(treap &left) { root_ = node::merge(left.root_, root_); left.root_ = nullptr; } void merge_right(treap &right) { root_ = node::merge(root_, right.root_); right.root_ = nullptr; } std::pair<treap, treap> split(int k) { node *l, *r; std::tie(l, r) = node::split(root_, k); return std::make_pair(treap(l), treap(r)); } void reverse(int l, int r) { node::reverse(root_, l, r); } void set(int k, const value_type &value) { node::update_node(root_, k, value); } value_type get(int k) { return (node::get_node(root_, k))->value; } value_type operator[](int k) { return get(k); } value_type fold() { return node::sum(root_); } value_type fold(int l, int r) { node *left, *mid, *right; std::tie(mid, right) = node::split(root_, r); std::tie(left, mid) = node::split(mid, l); auto ret = node::sum(mid); mid = node::merge(left, mid); root_ = node::merge(mid, right); return ret; } template <typename Func> void traverse(const Func &f) { node::traverse(root_, f); } void push_front(const value_type &val) { insert(0, val); } void push_back(const value_type &val) { insert(size(), val); } void pop_front() { erase(0); } void pop_back() { erase(size() - 1); } const value_type &front() { return get(0); } const value_type &back() { return get(size() - 1); } }; } // namespace haar_lib #line 2 "Mylib/IO/input_tuples.cpp" #include <initializer_list> #line 6 "Mylib/IO/input_tuples.cpp" #include <vector> #line 6 "Mylib/IO/input_tuple.cpp" namespace haar_lib { template <typename T, size_t... I> static void input_tuple_helper(std::istream &s, T &val, std::index_sequence<I...>) { (void) std::initializer_list<int>{(void(s >> std::get<I>(val)), 0)...}; } template <typename T, typename U> std::istream &operator>>(std::istream &s, std::pair<T, U> &value) { s >> value.first >> value.second; return s; } template <typename... Args> std::istream &operator>>(std::istream &s, std::tuple<Args...> &value) { input_tuple_helper(s, value, std::make_index_sequence<sizeof...(Args)>()); return s; } } // namespace haar_lib #line 8 "Mylib/IO/input_tuples.cpp" namespace haar_lib { template <typename... Args> class InputTuples { struct iter { using value_type = std::tuple<Args...>; value_type value; bool fetched = false; int N, c = 0; value_type operator*() { if (not fetched) { std::cin >> value; } return value; } void operator++() { ++c; fetched = false; } bool operator!=(iter &) const { return c < N; } iter(int N) : N(N) {} }; int N; public: InputTuples(int N) : N(N) {} iter begin() const { return iter(N); } iter end() const { return iter(N); } }; template <typename... Args> auto input_tuples(int N) { return InputTuples<Args...>(N); } } // namespace haar_lib #line 8 "Mylib/IO/input_tuples_with_index.cpp" namespace haar_lib { template <typename... Args> class InputTuplesWithIndex { struct iter { using value_type = std::tuple<int, Args...>; value_type value; bool fetched = false; int N; int c = 0; value_type operator*() { if (not fetched) { std::tuple<Args...> temp; std::cin >> temp; value = std::tuple_cat(std::make_tuple(c), temp); } return value; } void operator++() { ++c; fetched = false; } bool operator!=(iter &) const { return c < N; } iter(int N) : N(N) {} }; int N; public: InputTuplesWithIndex(int N) : N(N) {} iter begin() const { return iter(N); } iter end() const { return iter(N); } }; template <typename... Args> auto input_tuples_with_index(int N) { return InputTuplesWithIndex<Args...>(N); } } // namespace haar_lib #line 8 "test/aoj/1508/main.treap.test.cpp" namespace hl = haar_lib; int main() { int n, q; std::cin >> n >> q; hl::treap<hl::min_monoid<int>> s(n); for (auto [i, a] : hl::input_tuples_with_index<int>(n)) { s.set(i, {a}); } for (auto [x, y, z] : hl::input_tuples<int, int, int>(q)) { if (x == 0) { auto temp = s.get(z).value(); s.erase(z); s.insert(y, {temp}); } else if (x == 1) { auto ans = s.fold(y, z + 1).value(); std::cout << ans << std::endl; } else { s.set(y, z); } } return 0; }