#include using namespace std; using ll = long long; using ull = unsigned long long; mt19937 mt(736); template class treap { struct node { using nodeptr = shared_ptr; T x; nodeptr l, r; size_t sz; explicit node(T x) : x(x), l(nullptr), r(nullptr), sz(1) {} explicit node(T x, nodeptr l, nodeptr r) : x(x), l(l), r(r), sz(size(l) + 1 + size(r)) {} }; using nodeptr = typename node::nodeptr; static nodeptr make_node(T x) { return make_shared(x); } static nodeptr make_node(T x, nodeptr l, nodeptr r) { return make_shared(x, l, r); } static size_t size(const nodeptr &h) { return h == nullptr ? T{0} : h->sz; } static nodeptr merge(nodeptr le, nodeptr ri) { if (le == nullptr) return std::move(ri); if (ri == nullptr) return std::move(le); if (uniform_int_distribution{0, size(le) + size(ri) - 1}(mt) < size(le)) { auto rch = merge(le->r, std::move(ri)); return make_node(le->x, le->l, rch); } else { auto lch = merge(std::move(le), std::move(ri->l)); return make_node(ri->x, lch, ri->r); } } static pair split(const nodeptr &h, auto &&fn) // C++20 { if (h == nullptr) return {nullptr, nullptr}; if (fn(h)) { auto [le, ri] = split(h->r, std::forward(fn)); // structured binding, C++17 return {make_node(h->x, h->l, le), std::move(ri)}; } else { auto [le, ri] = split(h->l, std::forward(fn)); return {std::move(le), make_node(h->x, ri, h->r)}; } } static auto split_by_key(nodeptr h, const T &x) { return split(h, [&x](const nodeptr &h) { return h->x < x; }); } static auto split_by_size(nodeptr h, size_t k) { return split(h, [&k](const nodeptr &h) { if (auto ind = size(h->l); ind < k) { k -= ind + 1; return true; } else return false; }); } static nodeptr erase(nodeptr &&h, const T &x) { assert(h != nullptr); if (h->x == x) return merge(std::move(h->l), std::move(h->r)); if (h->x < x) { auto res = erase(std::move(h->r), x); h->r = std::move(res); upd(*h); return std::move(h); } else { auto res = erase(std::move(h->l), x); h->l = std::move(res); upd(*h); return std::move(h); } } nodeptr root = nullptr; public: [[nodiscard]] auto size() const { return size(root); } void insert(size_t k, T x) { auto [le, ri] = split_by_size(std::move(root), k); root = merge(std::move(le), merge(make_node(x), std::move(ri))); } const T &operator[](size_t k) const { auto [le, tmp] = split_by_size(root, k); auto [mi, ri] = split_by_size(std::move(tmp), 1); assert(mi != nullptr); const auto &ans = mi->x; return ans; } }; void solve(istream &cin = std::cin, ostream &cout = std::cout) { treap tr; int q; cin >> q; for (int i = 0; i < q; i++) { int type; cin >> type; if (type == 1) { int k, x; cin >> k >> x; tr.insert(k, x); } else if (type == 0) { int k; cin >> k; cout << tr[k] << '\n'; } else assert(false); } } void stress(istream &cin = std::cin, ostream &cout = std::cout) { vector tr; int q; cin >> q; for (int i = 0; i < q; i++) { int type; cin >> type; if (type == 1) { int k, x; cin >> k >> x; tr.insert(tr.begin() + k, x); } else if (type == 0) { int k; cin >> k; cout << tr[k] << '\n'; } else assert(false); } } void gen(ostream &cout = std::cout) { int q = 10; cout << q << endl; uniform_int_distribution type(0, 1), uid(0, 10); for (int i = 0, sz = 0; i < q; i++) { if (sz == 0 || type(mt)) cout << "1 " << mt() % (++sz) << ' ' << uid(mt) << endl; else cout << "0 " << mt() % sz << endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout << fixed; #ifdef LOCAL auto st = chrono::steady_clock::now(); ifstream fin("../input.txt"); do { solve(fin); cout << "===" << endl; string str; while (getline(fin, str) && str != string(max(1, (int) str.size()), '=')); } while (fin); #ifdef STRESS for (int cnt = 1;; cnt++) { stringstream ss, in1, out1, in2, out2; gen(ss); in1 << ss.str(); in2 << ss.str(); solve(in1, out1); stress(in2, out2); if (out1.str() != out2.str()) { cout << "fail: " << cnt << endl; cout << ss.str(); cout << "solve:" << endl; cout << out1.str(); cout << "stress:" << endl; cout << out2.str(); break; } else if (cnt % 100 == 0) cout << "ok: " << cnt << endl; } #endif cout << setprecision((int) floor(log10(chrono::steady_clock::duration::period::den))); cout << "clock: " << chrono::duration(chrono::steady_clock::now() - st).count() << endl; #else solve(); #endif return 0; }