Cod sursa(job #386840)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 26 ianuarie 2010 10:36:54
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.09 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#define Gets(nod)   (nod -> size = (nod == nil) ? nod -> size : nod -> left -> size + 1 + nod -> right -> size)

struct treap {
    int key, priority, size;
    bool reversed;
    treap * left, * right;
} * R, * nil;

treap * rev (treap * nod) {
    if (nod == nil) return nod;
    if (nod -> reversed) {
        nod -> reversed = 0;
//        fprintf(stderr, "%d %d\n", nod -> key, nod -> size);
        treap * aux = nod -> left; nod -> left = nod -> right; nod -> right = aux;
        nod -> left -> reversed ^= 1;
	   	nod -> right -> reversed ^= 1;
    }
    return nod;
}

treap * rotleft (treap * nod) {
    treap * t = nod -> right;
    nod -> right = t -> left;
    t -> left = nod;
    Gets(nod);
    Gets(t);
    return t;
}

treap * rotright (treap * nod) {
    treap * t = nod -> left;
    nod -> left = t -> right;
    t -> right = nod;
    Gets(nod);
    Gets(t);
    return t;
}

treap * balance (treap * nod) {
    nod = rev(nod); nod -> left = rev(nod -> left); nod -> right = rev(nod -> right);
    Gets(nod);
    int max = nod -> priority;
    if (nod -> left -> priority > max)
        max = nod -> left -> priority;
    if (nod -> right -> priority > max)
        max = nod -> right -> priority;

    if (max == nod -> left -> priority)
        nod = rotright(nod);
    else if (max == nod -> right -> priority)
        nod = rotleft(nod);
    return nod;
}

treap * insert (treap * nod, int poz, int val, int pr) {
    nod = rev(nod);
    
    if (nod == nil) {
        treap * x = new treap;
        x -> key = val;
        x -> priority = pr;
        x -> left = x -> right = nil;
        x -> size = 1; x -> reversed = false;
        return x;
    }

    //fprintf(stderr, "INSERT : NOD : %d | size : %d | %d %d %d %d %d\n", nod -> key, nod -> size, poz, val, pr, nod -> left -> size, nod -> right -> size);

    if (nod -> left -> size + 1 >= poz)
        nod -> left = insert(nod -> left, poz, val, pr);
    else
        nod -> right = insert(nod -> right, poz - nod -> left -> size - 1, val, pr);

    nod = balance(nod);
    return nod;
}

int search (treap * nod, int poz) {
    nod = rev(nod);
    if (nod -> left -> size >= poz)
        return search (nod -> left, poz);
    if (nod -> left -> size + 1 == poz)
        return nod -> key;
    if (nod -> left -> size + 1 < poz)
        return search (nod -> right, poz - nod -> left -> size - 1);
    assert(false);
}

treap * erase_it (treap * nod) {
    nod = rev(nod);
 //   fprintf(stderr, "%d %d %d %d\n", nod -> key, nod -> size, nod -> left -> key, nod -> right -> key);
    if (nod -> left == nil && nod -> right == nil)
        return nil;
    nod = balance(nod);
  //  fprintf(stdout, "BIBAN: %d\n", nod -> key); fflush(stdout);
    if (nod -> left -> key == -1)
        nod -> left = erase_it(nod -> left);
    else if (nod -> right -> key == -1)
        nod -> right = erase_it(nod -> right);
    nod = balance(nod);
    return nod;
}

void print (treap * nod) {
    nod = rev(nod);
    if (nod == nil)
        return;
    print(nod -> left);
    printf("%d ", nod -> key);
    print(nod -> right);
}

void split (treap * nod, int poz, treap * & tr1, treap * & tr2) {
    nod = insert(nod, poz, -1, 2100000000);
    tr1 = nod -> left; tr2 = nod -> right;
}

treap * join (treap * tr1, treap * tr2) {
    treap * nod = new treap;
    nod -> left = tr1; nod -> right = tr2; nod -> priority = 0; nod -> key = -1; Gets(nod);
    nod = erase_it (nod);
    return nod;
}

treap * erase (treap * x, int first, int last) {
    treap * tr1, * tr2, * tr3, * tr4;
    split(x, first, tr1, tr3);
    split(tr3, last - first + 2, tr4, tr2);
    x = join(tr1, tr2);
    return x;
}

treap * reverse (treap * nod, int first, int last) {
    treap * tr1, * tr2, * tr3, * tr4;
    nod = rev(nod);
    split(nod, first, tr1, tr2);
    split(tr2, last - first + 2, tr3, tr4);
    //print(tr1); puts("");print(tr2); puts("");
    tr3 -> reversed ^= 1;
    //print(tr3); puts("");print(tr4); puts("");

    if (tr4 -> size)
        tr2 = join(tr3, tr4);
    else
        tr2 = tr3;
    nod = join(tr1, tr2);
    //print(tr2); puts("");print(nod); puts("");

    //fprintf(stderr, "%d %d %d %d\n", nod -> left -> size, nod -> size, first, last);
   
    return nod;
}

int main () {
    int N, poz, val, first, last, i, x;
    char tip;

    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    scanf("%d%d", &N, &x);

    R = nil = new treap;

    for (i = 1; i <= N; ++ i) {
        scanf(" %c", &tip);
//        fprintf(stderr, "x%c\n", tip);
        if (tip == 'I') {
            scanf("%d%d", &poz, &val);
            R = insert(R, poz, val, rand () % 2000000000);
        } else if (tip == 'A') {
            scanf("%d", &poz);
            fprintf(stdout, "%d\n", search(R, poz));
        } else if (tip == 'D') {
            scanf("%d%d", &first, &last);
            R = erase(R, first, last);
        } else if (tip == 'R') {
            scanf("%d%d", &first, &last);
            R = reverse(R, first, last);
        } else assert(false);
//        print(R);
  //      puts("");
    //    fflush(stdout);
    }
    print(R);
}