Cod sursa(job #1509263)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 23 octombrie 2015 17:04:15
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.32 kb
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <algorithm>

const int Pmask = 1048575;

struct Treap {
    int key, priority;
    int siz;
    bool rev;
    Treap *l, *r;
    Treap (int k, int p, int s, Treap *left, Treap *right) {
        key = k;
        priority = p;
        rev = 0;
        siz = s;
        l = left;
        r = right;
    }
};

Treap *R, *NIL;

inline unsigned xor128(void) {
    static unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;
    unsigned t;
    t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    w = w ^ (w >> 19) ^ (t ^ (t >> 8));
    return w;
}

inline void lazy(Treap* &N) {
    if (N != NIL && N->rev) {
        N->rev = 0;
        N->l->rev ^= 1;
        N->r->rev ^= 1;
        std::swap(N->l, N->r);
    }
}

inline void update(Treap* &N) {
    lazy(N);
    lazy(N->l);
    lazy(N->r);
    N->siz = N->l->siz + N->r->siz + 1;
}

inline void rotLeft(Treap* &N) {
    Treap *T = N->l;
    N->l = T->r;
    T->r = N;
    update(N);
    N = T;
    update(N);
}

inline void rotRight(Treap* &N) {
    Treap *T = N->r;
    N->r = T->l;
    T->l = N;
    update(N);
    N = T;
    update(N);
}

void balance(Treap* &N) {
    update(N);
    if (N->l->priority > N->priority) {
        rotLeft(N);
    } else if (N->r->priority > N->priority) {
        rotRight(N);
    }
    update(N);
}

void treapInsert(Treap* &N, int key, int position, int priority) {
    if (N == NIL) {
        N = new Treap(key, priority, 1, NIL, NIL);
        return;
    }
    update(N);
    if (position <= N->l->siz) {
        treapInsert(N->l, key, position, priority);
    } else {
        treapInsert(N->r, key, position - N->l->siz - 1, priority);
    }
    balance(N);
}

void inOrder(Treap* &N) {
    if (N == NIL) {
        return;
    }
    update(N);
    inOrder(N->l);
    printf("%d ", N->key);
    inOrder(N->r);
}

void treapErase(Treap* &N, int position) {
    if (N == NIL) {
        return;
    }
    update(N);
    if (position <= N->l->siz) {
        treapErase(N->l, position);
    } else if (position > N->l->siz + 1) {
        treapErase(N->r, position - N->l->siz - 1);
    } else {
        if (N->l == NIL && N->r == NIL) {
            delete N;
            N = NIL;
        } else {
            if (N->l->priority > N->r->priority) {
                rotLeft(N);
                treapErase(N->r, position - N->l->siz - 1);
            } else {
                rotRight(N);
                treapErase(N->l, position);
            }
        }
    }
    if (N != NIL) {
        update(N);
    }
}

int treapGet(Treap* &N, int position) {
    if (N == NIL) {
        return -1;
    }
    update(N);
    if (position == N->l->siz + 1) {
        return N->key;
    } else if (position <= N->l->siz) {
        return treapGet(N->l, position);
    } else {
        return treapGet(N->r, position - N->l->siz - 1);
    }
}

void split(Treap* &N, int position, Treap* &L, Treap* &R) {
    treapInsert(N, 0, position, Pmask + 2);
    L = N->l;
    R = N->r;
    delete N;
    N = NIL;
}

void join(Treap* &N, int position, Treap* &L, Treap* &R) {
    N = new Treap(0, 0, L->siz + R->siz + 1, L, R);
    update(N);
    treapErase(N, L->siz + 1);
}

int main(void) {
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    Treap *Tl, *Tr, *TL, *TR; // dummy Treap
    char opType;
    int n, x, y;

    R = NIL = new Treap(0, 0, 0, NULL, NULL);

    scanf("%d%d", &n, &x);
    while (n--) {
        scanf(" %c", &opType);
        if (opType == 'I') {
            scanf("%d%d", &x, &y);
            treapInsert(R, y, x - 1, (xor128() & Pmask) + 1);
        } else if (opType == 'A') {
            scanf("%d", &x);
            printf("%d\n", treapGet(R, x));
        } else if (opType == 'R') {
            scanf("%d%d", &x, &y);
            split(R, y, Tl, Tr);
            split(Tl, x - 1, TL, TR);
            TR->rev ^= 1;
            join(Tl, x - 1, TL, TR);
            join(R, y, Tl, Tr);
        } else {
             scanf("%d%d", &x, &y);
             split(R, y, Tl, Tr);
             split(Tl, x - 1, TL, TR);
             join(R, y, TL, Tr);
        }
    }
    inOrder(R);

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