Cod sursa(job #1928352)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 16 martie 2017 03:53:39
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 8.95 kb
#include <iostream>
#include <cstdlib>
#include <functional>

using namespace std;

namespace treap {

int myRand() {
    return ((rand()&((1<<15))-1)<<15) + rand()&((1<<15)-1);
}

template<typename T>
struct Node {
    T val;
    int prio, sub;
    bool sw;
    Node *left, *right, *father;
 
    Node(const T& val) : val(val), prio(myRand()), left(NULL), right(NULL),
    father(NULL), sw(false), sub(1) {}
 
    int leftSize() const {
        return (left == NULL ? 0 : left->sub);
    }
 
    void update() {
        sub = 1;
        if (left != NULL) {
            sub += left->sub;
            left->father = this;
        }
        if (right != NULL) {
            sub += right->sub;
            right->father = this;
        }
    }
 
    void lazy() {
        if (sw) {
            swap(left, right);
            if (left != NULL)
                left->sw ^= 1;
            if (right != NULL)
                right->sw ^= 1;
            sw = false;
        }
    }
};

template<typename T>
class Iterator {
    Node<T>* current;
    int rank;

  public: 
    Iterator(Node<T>* current, int rank=0) : current(current), rank(rank) {}

    Iterator operator ++() {
        if (current->right != NULL) {
            current = current->right;
            current->lazy();
            while (current->left != NULL) {
                current = current->left;
                current->lazy();
            }
        } else {
            Node<T>* last = current;
            current = current->father;
            while (current != NULL) {
                if (last == current->left) {
                    break;
                }
                last = current;
                current = current->father;
            }
        }
        ++rank;
    }

    int getRank() {
        return rank;
    }

    bool invalid() {
        return current == NULL;
    }

    T getValue() {
        return current->val;
    }
};

template<typename T>
class Treap {
    Node<T>* root;
    int sz;
    int aux;
     
    // First k-1 nodes in L, everything else in R.
    void splitAtKth(Node<T>* C, Node<T>*& L, Node<T>*& R, int k) {
        if (C == NULL) {
            L = NULL;
            R = NULL;
            return;
        }
     
        C->lazy();
     
        if (C->leftSize() + 1 < k) {
            L = C;
            splitAtKth(C->right, L->right, R, k - C->leftSize() - 1);
            L->update();
        } else {
            R = C;
            splitAtKth(C->left, L, R->left, k);
            R->update();
        }
    }
    
    void insertAtKth(Node<T>*& C, Node<T>* N, int k) {
        if (C == NULL) {
            C = N;
            return;
        }
     
        C->lazy();
     
        if (N->prio < C->prio) {
            Node<T> *L, *R;
            splitAtKth(C, L, R, k);
            C = N;
            C->left = L;
            C->right = R;
            ++sz;
        } else if (C->leftSize() >= k-1) {
            insertAtKth(C->left, N, k);
        } else {
            insertAtKth(C->right, N, k - C->leftSize() - 1);
        }

        C->update();
    }

    // All nodes smaller than or equal to comp in L, everything else in R
    void splitByComparison(Node<T>* C, Node<T>*& L, Node<T>*& R, const T& comp) {
        if (C == NULL) {
            L = NULL;
            R = NULL;
        }

        C->lazy();

        if (C->val <= comp) {
            L = C;
            splitByComparison(C->right, L->right, R, comp);
            L->update();
        } else {
            R = C;
            splitByComparison(C->left, L, R->left, comp);
            R->update();
        }
    }

    void insertByComparison(Node<T>*& C, Node<T>* N) {
        if (C == NULL) {
            C = N;
            return;
        }

        C->lazy();
     
        if (N->prio < C->prio) {
            Node<T> *L, *R;
            split(C, L, R, N->val);
            C = N;
            C->left = L;
            C->right = R;
            ++sz;
        } else if (N->val <= C->val) {
            insertByComparison(C->left, N);
        } else {
            insertByComparison(C->right, N);
        }

        C->update();
    }

    void join(Node<T>*& C, Node<T>* L, Node<T>* R) {
        if (L == NULL) {
            C = R;
            return;
        }
        if (R == NULL) {
            C = L;
            return;
        }
     
        L->lazy();
        R->lazy();
     
        if(L->prio < R->prio) {
            C = L;
            join(C->right, L->right, R);
            C->update();
        } else {
            C = R;
            join(C->left, L, R->left);
            C->update();
        }
    }
     
    void eraseKth(Node<T>*& C, int k) {
        C->lazy();
        if (C->leftSize() + 1 == k) {
            Node<T> *L = C->left, *R = C->right;
            delete C;
            C = NULL;
            join(C, L, R);
            --sz;
        } else if (C->leftSize() >= k-1) {
            eraseKth(C->left, k);
        } else {
            eraseKth(C->right, k - C->leftSize() - 1);
        }
        if (C != NULL)
            C->update();
    }

    void eraseByComparison(Node<T>*& C, const T& val) {
        if (C == NULL)
            return;
        C->lazy();
        if (C->val == val) {
            Node<T> *L = C->left, *R = C->right;
            delete C;
            C = NULL;
            join(C, L, R);
            --sz;
        } else if (val <= C->val) {
            eraseByComparison(C->left, val);
        } else {
            eraseByComparison(C->right, val);
        }
        if (C != NULL)
            C->update();
    }
     
    Iterator<T> getKth(Node<T>* C, int k) {
        C->lazy();
     
        if (C->leftSize() + 1 == k) {
            return Iterator<T>(C, aux);
        } else if (C->leftSize() >= k-1) {
            getKth(C->left, k);
        } else {
            getKth(C->right, k - C->leftSize() - 1);
        }
    }

    Iterator<T> firstSatisfying(Node<T>* C, const T& val, 
        const function<bool (const T&, const T&)>& comp) {
        if (C == NULL) {
            return Iterator<T>(NULL);
        }

        C->lazy();

        if (comp(val, C->val)) {
            auto it = firstSatisfying(C->left, val, comp);
            if (it.invalid()) {
                it = Iterator<T>(C, aux + 1);
            }
            return it;
        } else {
            aux += C->leftSize() + 1;
            return firstSatisfying(C->right, val, comp);
        }
    }

  public:

    Treap() : root(NULL), sz(0) {}

    void insertAtKth(const T& val, int k) {
        Node<T> *N = new Node<T>(val);
        insertAtKth(root, N, k);
    }

    // Needs operator <= defined on T.
    void insertByComparison(const T& val) {
        Node<T> *N = new Node<T>(val);
        insertByComparison(root, N);
    }

    bool eraseKth(int k) {
        int oldSz = sz;
        eraseKth(root, k);
        if (root != NULL) {
            root->father = NULL;
        }
        return sz < oldSz;
    }

    // Erases one instance of val.
    // Needs operator == and <= defined on T.
    bool eraseByComparison(const T& val) {
        int oldSz = sz;
        eraseByComparison(root, val);
        if (root != NULL) {
            root->father = NULL;
        }
        return sz < oldSz;
    }

    Iterator<T> getKth(int k) {
        aux = k;
        return getKth(root, k);
    }

    Iterator<T> first() {
        return getKth(1);
    }

    Iterator<T> last() {
        return getKth(sz);
    }

    // Requires operator <= defined on T.
    Iterator<T> lowerBound(const T& val) {
        aux = 0;
        return firstSatisfying(root, val, [](const T& a, const T& b) {
            return a <= b;
        });
    }

    // Requires operator < defined on T.
    Iterator<T> upperBound(const T& val) {
        aux = 0;
        return firstSatisfying(root, val, [](const T& a, const T& b) {
            return a < b;
        });
    }

    void reverse(int i, int j) {
        Node<T> *T12, *T1, *T2, *T3;
        splitAtKth(root, T12, T3, j+1);
        splitAtKth(T12, T1, T2, i);
        if (T2 != NULL) {
            T2->sw ^= 1;
        }
        join(T12, T1, T2);
        join(root, T12, T3);
    }
     
    // Requires operator << between ostream and T.
    void printAll(ostream& out) {
        for (Iterator<T> it = first(); !it.invalid(); ++it) {
            out << it.getValue() << " ";
        }
    }

    int size() const {
        return sz;
    }
};

}

int main() {
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    treap::Treap<int> t;
    
    int n, op;
    cin >> n >> op;

    for (int i = 1; i <= n; ++i) {
        char op;
        cin >> op;
        if (op == 'I') {
            int k, e;
            cin >> k >> e;
            t.insertAtKth(e, k);
        } else if (op == 'A') {
            int k;
            cin >> k;
            cout << t.getKth(k).getValue() << "\n";
        } else if (op == 'R') {
            int l, r;
            cin >> l >> r;
            t.reverse(l, r);
        } else {
            int l, r;
            cin >> l >> r;
            for (int j = l; j <= r; ++j) {
                t.eraseKth(l);
            }
        }
    }
    t.printAll(cout);
}