Cod sursa(job #1739755)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 10 august 2016 04:29:32
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.22 kb
// Inspirata de la tovarasul Tamio
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

namespace Treap {
    struct T { //Treap node
        static T *NIL;

        int  key, size, p;
        bool rev;

        T *st, *dr;

        inline T() {}
        inline T(int _key, T *_st = NIL, T *_dr = NIL) {
            size = 1;
            rev  = false;
            key  = _key;
            st   = _st;
            dr   = _dr;
            p    = rand() + 1;
        }
    };

    T *T::NIL = new T();

    void init(void) {
        srand(time(NULL));
        T::NIL->size = NULL; // :(
        T::NIL->rev  = NULL; // :(
        T::NIL->st   = NULL;
        T::NIL->dr   = NULL;
        T::NIL->p    = NULL; // :(
    }

#define NIL T::NIL

    void getSize(T *nod) {
        nod->size = (nod->st->size) + 1 + (nod->dr->size);
    }

    void prop(T *nod) {
        if(nod->rev) {
            nod->rev = false;
            swap(nod->st, nod->dr);

            if(nod->st != NIL) nod->st->rev ^= 1;
            if(nod->dr != NIL) nod->dr->rev ^= 1;
        }
    }

    T *join(T *st, T *dr) {
        if(st == NIL) return dr;
        if(dr == NIL) return st;

        prop(st);
        prop(dr);

        if(st->p > dr->p) {
            st->dr = join(st->dr, dr);
            getSize(st);
            return st;
        }
        else {
            dr->st = join(st, dr->st);
            getSize(dr);
            return dr;
        }
    }

    T *kth(T *nod, int pos) {
        if(nod->st->size == pos) return nod;
        if(nod->st->size > pos)  return kth(nod->st, pos);
        if(nod->st->size < pos)  return kth(nod->dr, pos - nod->st->size - 1);
    }

    pair<T*, T*> split(T *nod, int pos) {
        if(nod == NIL) return make_pair(NIL, NIL);
        prop(nod);

        if(nod->st->size == pos) {
            T *tmp = nod->st;
            nod->st = NIL;
            getSize(nod);
            return make_pair(tmp, nod);
        }
        else if(nod->st->size < pos) {
            pair<T*, T*> tmp = split(nod->dr, pos - 1 - nod->st->size);
            nod->dr = tmp.first;
            tmp.first = nod;
            getSize(nod);
            return tmp;
        }
        else {
            pair<T*, T*> tmp = split(nod->st, pos);
            nod->st = tmp.second;
            tmp.second = nod;
            getSize(nod);
            return tmp;
        }
    }

    void show(T *nod) {
        if(nod == NIL)
            return;
        show(nod->st);
        printf("%d ",nod->key);
        show(nod->dr);
    }

    tuple<T*, T*, T*> split3(T* nod, int a, int b) {
        auto x = split(nod, b),
             y = split(x.first, a);
            return make_tuple(y.first, y.second, x.second);
    }

    T *insert(T *nod, int pos, int key) {
        auto tmp = split(nod, pos);
        return join( join(tmp.first, new T(key)), tmp.second );
    }

    T *remove(T *nod, int a, int b) {
        auto deld = split3(nod, a, b);
        return join(get<0>(deld), get<2>(deld));
    }

    T *reverse(T *nod, int a, int b) {
        auto revd = split3(nod, a, b);
        get<1>(revd)->rev ^= 1;
        return join( join(get<0>(revd), get<1>(revd)), get<2>(revd) );
    }
};


int main(void) {
    freopen("secv8.in", "r",  stdin);
    freopen("secv8.out", "w", stdout);
    Treap::init();
    Treap::T *root = Treap::NIL;
    int n, m;

    scanf("%d%d ",&n);

    while(n--) {
        int  a, b;
        char op;

        scanf("%c ",&op);

        switch(op) {
        case 'A': {
            scanf("%d ",&a);
            printf("%d\n", (Treap::kth(root, a-1)->key) );
            break; }

        case 'D': {
            scanf("%d%d ",&a,&b);
            root = Treap::remove(root,  a-1, b);
            break; }

        case 'I': {
            scanf("%d%d ",&a,&b);
            root = Treap::insert(root,  a-1, b);
            break; }

        case 'R': {
            scanf("%d%d ",&a,&b);
            root = Treap::reverse(root, a-1, b);
            break; }
        }
    }

    Treap::show(root);
    printf("\n");

    fclose(stdin);
    fclose(stdout);
    return 0;
}

// Just hunting for Red October...