Cod sursa(job #3123558)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 24 aprilie 2023 17:45:17
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.53 kb
#ifndef LOCAL
    #pragma GCC optimize("Ofast")
#endif // LOCAL
#include <bits/stdc++.h>

using namespace std;

static char buf[60 << 20];
void* operator new(size_t s) {
	static size_t i = sizeof buf;
	assert(s < i);
	return (void*)&buf[i -= s];
}
void operator delete(void*) {}

struct RNG {
    uint64_t x; /* The state can be seeded with any value. */

    uint64_t next() {
        uint64_t z = (x += 0x9e3779b97f4a7c15);
        z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
        z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
        return z ^ (z >> 31);
    }

    RNG(uint64_t _x) { x = _x; }
} rng(123);

template < typename Data >
struct RevImplicitTreap {
    struct Node {
        bool rev;
        Data data;

        int32_t size;
        uint32_t prio;

        Node *left, *right;

        Node(Data _data) {
            rev = false; data = _data;
            size = 1; prio = rng.next();
            left = right = nullptr;
        }
    } *head;

    static int get_size(Node *x) { return x == nullptr ? 0 : x->size; }
    static int get_prio(Node *x) { return x == nullptr ? 0 : x->prio; }
    static void update(Node *x) {
        if(x == nullptr) return;
        x->size = 1 + get_size(x->left) + get_size(x->right);
    }
    static void push(Node *x) {
        if(x == nullptr) return;

        if(x->left != nullptr) x->left->rev ^= x->rev;
        if(x->right != nullptr) x->right->rev ^= x->rev;

        if(x->rev) swap(x->left, x->right);
        x->rev = 0;

        // Not needed because size does not depend on lazy
        /// update(x);

        return;
    }

    RevImplicitTreap() { head = nullptr; }
    RevImplicitTreap(Data _data) { head = new Node(_data); }

    static Node* merge(Node* l, Node* r) {
        push(l); push(r);
        if(l == nullptr) return r;
        if(r == nullptr) return l;

        if(get_prio(l) > get_prio(r)) {
            /// l as root
            l->right = merge(l->right, r);
            update(l);

            return l;
        }
        else {
            /// r as root
            r->left = merge(l, r->left);
            update(r);

            return r;
        }
    }

    static pair<Node*, Node*> split(Node* root, int cnt) {
        push(root);

        if(root == nullptr) {
            #ifdef LOCAL
                assert(cnt == 0);
            #endif // LOCAL
            return {nullptr, nullptr};
        }

        if(get_size(root->left) + 1 <= cnt) {
            pair<Node*, Node*> n = split(root->right, cnt - 1 - get_size(root->left));
            root->right = n.first; update(root);

            return {root, n.second};
        }
        else {
            pair<Node*, Node*> n = split(root->left, cnt);
            root->left = n.second; update(root);

            return {n.first, root};
        }
    }

    static Data& access(Node* root, int cnt) {
        push(root);

        if(get_size(root->left) + 1 == cnt) return root->data;
        else if(get_size(root->left) >= cnt) return access(root->left, cnt);
        else { return access(root->right, cnt - 1 - get_size(root->left)); }
    }

    static void _prt(Node *h, ostream& out) {
        push(h);
        if(h == nullptr) return;

        _prt(h->left, out); out << h->data << ' '; _prt(h->right, out);
    }

    Data& operator[](int ind) {
        return access(head, ind);
    }
};

#define RIT RevImplicitTreap<T>
#define Node (typename RevImplicitTreap<T>::Node)

template < typename T >
ostream& operator<<(ostream& out, RIT x) {
    RIT::_prt(x.head, out);

    return out;
}

template < typename T >
RIT merge(RIT a, RIT b) {
    RIT ret;
    ret.head = RIT::merge(a.head, b.head);
    return ret;
}

template < typename T >
pair<RIT, RIT> split(RIT a, int cnt) {
    auto pr = RIT::split(a.head, cnt);
    pair<RIT, RIT> ret;
    ret.first.head = pr.first;
    ret.second.head = pr.second;

    return ret;
}

template < typename T >
RIT reverse(RIT x) {
    if(x.head == nullptr) return x;
    x.head->rev ^= 1;
    return x;
}

#undef RIT
#undef Node

#ifndef LOCAL
ifstream in("secv8.in");
ofstream out("secv8.out");
#define cin in
#define cout out
#endif // LOCAL

signed main()
{
    #ifndef LOCAL
        ios_base::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    #endif // LOCAL

    RevImplicitTreap<int> x;

    int q; cin >> q;
    int _trash; cin >> _trash;

    while(q--) {
        char t; cin >> t;

        if(t == 'I') {
            int k, e; cin >> k >> e;
            auto pr = split(x, k - 1);

            x = merge(merge(pr.first, {e}), pr.second);
        }

        if(t == 'A') {
            int k; cin >> k;
            // auto l = split(x, k - 1);
            // auto r = split(l.second, 1);

            #ifdef LOCAL
                cerr << "\t\t";
            #endif // LOCAL
            cout << x[k] << '\n';
        }

        if(t == 'R') {
            int l, r; cin >> l >> r;

            auto tr = split(x, r);
            auto tl = split(tr.first, l - 1);

            tl.second = reverse(tl.second);

            x = merge(merge(tl.first, tl.second), tr.second);
        }

        if(t == 'D') {
            int l, r; cin >> l >> r;

            auto tr = split(x, r);
            auto tl = split(tr.first, l - 1);

            x = merge(tl.first, tr.second);
        }

        #ifdef LOCAL
            cerr << "\t\t" << x << endl;
        #endif // LOCAL
    }

    cout << x << '\n';

    return 0;
}