Cod sursa(job #2060182)

Utilizator cristina_borzaCristina Borza cristina_borza Data 7 noiembrie 2017 22:23:13
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.54 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("secv8.in");
ofstream g ("secv8.out");

int n, useless, pos, p1, p2, val;
char op;

struct Treap {
    int value, weight, rev;
    unsigned long long key;

    Treap* left;
    Treap* right;
};

Treap* emptyTreap = new Treap {
    0, 0, 0,
    0,
    NULL, NULL
};

Treap* NewTreap (int value) {
    Treap* root = new Treap ();

    root -> value = value;
    root -> weight = 1;
    root -> rev = 0;

    root -> left = emptyTreap;
    root -> right = emptyTreap;

    root -> key = ((unsigned long long) rand() << 0)
                ^ ((unsigned long long) rand() << 15)
                ^ ((unsigned long long) rand() << 30)
                ^ ((unsigned long long) rand() << 45);

    if (root -> key == 0)
        root -> key = 1;

    return root;
}

void deleteTreap (Treap* root) {
    if (root -> left != emptyTreap)
        deleteTreap (root -> left);

    if (root -> right != emptyTreap)
        deleteTreap (root -> right);

    delete root;
}

Treap* UpdateTreap (Treap* root, Treap* newLeft, Treap* newRight) {
    Treap* newRoot = root;
    *newRoot = {
        root -> value,
        newLeft -> weight + 1 + newRight -> weight,

        root -> rev,
        root -> key,

        newLeft,
        newRight
    };

    return newRoot;
}

void propagation (Treap * root) {
    if (root -> rev == 0)
        return;

    root -> rev ^= 1;
    swap (root -> left, root -> right);

    if (root -> left != emptyTreap)
        root -> left -> rev ^= 1;
    if (root -> right != emptyTreap)
        root -> right -> rev ^= 1;
}

Treap* join (Treap* first, Treap* second) {
    if (first == emptyTreap) {
        return second;
    }

    if (second == emptyTreap) {
        return first;
    }

    propagation ( first );
    propagation ( second );

    if (first -> key >= second -> key) {
        UpdateTreap (first, first -> left, join (first -> right, second));
        return first;
    }

    UpdateTreap (second, join (first, second -> left), second -> right);
    return second;
}

pair <Treap*, Treap*> split (Treap* root, int pos) {
    if (root == emptyTreap) {
        return {emptyTreap, emptyTreap};
    }

    propagation ( root );
    if (root -> left -> weight == pos) {
        Treap* aux = root -> left;
        UpdateTreap (root, emptyTreap, root -> right);


        return {aux, root};
    }

    if (root -> left -> weight > pos) {
        auto aux = split (root -> left, pos);

        UpdateTreap (root, aux.second, root -> right);
        aux.second = root;

        return aux;
    }

    auto aux = split(root -> right, pos - root -> left -> weight - 1);
    UpdateTreap (root, root -> left, aux.first);

    aux.first = root;
    return aux;
}

Treap* insert (Treap *root, int pos, int value) {
    Treap *node = NewTreap (value);

    auto aux = split (root, pos);
    return join( join( aux.first, node ), aux.second );
}

int find (Treap *root, int pos ) {
    propagation ( root );
    if (root -> left -> weight == pos)
        return root -> value;
    if (root -> left -> weight > pos)
        return find (root -> left, pos);

    return find (root -> right, pos - root -> left -> weight - 1 );
}

Treap* reverse (Treap *root, int left, int right) {
    auto aux0 = split (root, left - 1);
    auto aux1 = split (aux0.second, right - left + 1);

    aux1.first -> rev ^= 1;
    return join (aux0.first, join (aux1.first, aux1.second));
}

Treap *erase (Treap *root, int left, int right) {
    auto aux0 = split (root, left - 1);
    auto aux1 = split (aux0.second, right - left + 1);

    return join (aux0.first, aux1.second);
}

void afis (Treap* root) {
    if (root == emptyTreap)
        return;

    propagation ( root );

    afis (root -> left);
    g << root -> value << " ";
    afis (root -> right);
}

int main() {

    srand( time( 0 ) );

    Treap* Root = emptyTreap;

    f >> n >> useless;
    for (int i = 1; i <= n; ++ i) {
        f >> op;
        if (op == 'I') {
            f >> pos >> val;
            Root = insert (Root, pos - 1, val);
        }


        if (op == 'A') {
            f >> pos;
            g << find (Root, pos - 1) << '\n';
        }

        if (op == 'R') {
            f >> p1 >> p2;
            Root = reverse (Root, p1, p2);
        }

        if (op == 'D') {
            f >> p1 >> p2;
            Root = erase (Root, p1, p2);
        }
    }

    afis ( Root );
    return 0;
}