Cod sursa(job #2023006)

Utilizator Theodor1000Cristea Theodor Stefan Theodor1000 Data 17 septembrie 2017 22:29:47
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.09 kb
#include <cstdio>
#include <algorithm>
#include <ctime>

using namespace std;

struct treap
{
    int val, pri, sub, inv;

    treap *le, *ri;

    treap ()
    {
        val = pri = inv = 0;
        sub = 1;
        le = ri = NULL;
    }

    treap (int v, int p, int su, int i, treap *l, treap *r)
    {
        val = v;
        pri = p;
        sub = su;
        inv = i;
        le = l;
        ri = r;
    }

} *root, *nul;

int ra ()
{
    return (rand () % 32000) * (rand () % 32000) + 1;
}

void check (treap* &nod)
{
    if (!(nod -> inv)) return;

    swap (nod->le, nod->ri);
    nod->le->inv ^= 1;
    nod->ri->inv ^= 1;
    nod->inv = 0;
}

void recount (treap* &nod)
{
    nod->sub = nod->le->sub + nod->ri->sub + 1;
}

void roleft (treap* &nod)
{
    treap* aux = nod->le;

    nod->le = aux->ri;
    aux->ri = nod;
    nod = aux;

    recount (nod);
    recount (nod->ri);
}

void roright (treap* &nod)
{
    treap* aux = nod->ri;

    nod->ri = aux->le;
    aux->le = nod;
    nod = aux;

    recount (nod);
    recount (nod->le);
}

void balance (treap* &nod)
{
    check (nod);

    if (nod->le->pri > nod->pri)
    {
        check (nod->le);
        roleft (nod);
    }

    else if (nod->ri->pri > nod->pri)
    {
        check (nod->ri);
        roright (nod);
    }
}

void inserare (treap* &nod, int poz, int vall, int p)
{
    if (nod == nul)
    {
        nod = new treap (vall, p, 0, 0, nul, nul);
        return;
    }

    check (nod);

    if (nod->le->sub >= poz) inserare (nod->le, poz, vall, p);
    else inserare (nod->ri, poz - nod->le->sub - 1, vall, p);

    recount (nod);
    balance (nod);
}

void sterge (treap* &nod, int poz)
{
    check (nod);

    if (nod->le->sub >= poz) sterge (nod->le, poz);
    else if (nod->le->sub + 1 < poz) sterge (nod->ri, poz - nod->le->sub - 1);
    else
    {
        if (nod->le == nul && nod->ri == nul)
        {
            nod = nul;
            return;
        }

        if (nod->le->pri > nod->ri->pri)
        {
            check (nod->le);
            roleft (nod);
        }

        else
        {
            check (nod->ri);
            roright (nod);
        }

        sterge (nod, poz);
    }

    if (nod != nul) recount (nod);
}

int fin (treap* &nod, int poz)
{
    check (nod);

    if (nod->le->sub + 1 == poz)
        return nod->val;

    if (nod->le->sub >= poz) return fin (nod->le, poz);
    else return fin (nod->ri, poz - nod->le->sub - 1);
}

void split (treap* &nod, int poz, treap* &t1, treap* &t2)
{
    inserare (nod, poz - 1, 0, 2000000000);
    t1 = nod->le;
    t2 = nod->ri;

    nod = new treap;
    nod = nul;
}

void join (treap* &nod, treap* &t1, treap* &t2)
{
    nod = new treap (0, -1, 0, 0, t1, t2);
    recount (nod);

    sterge (nod, t1->sub + 1);
}

void scrie (treap* &nod)
{
    if (nod == nul) return;

    scrie (nod->le);
    printf ("%d ", nod->val);
    scrie (nod->ri);
}

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

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

    nul = new treap;
    root = new treap;

    nul->sub = 0;
    root->le = root->ri = nul;

    srand (time (0));

    for (; n; --n)
    {
        char c;
        int x, y;
        scanf ("\n%c %d", &c, &x);

        if (c != 'A') scanf ("%d", &y);

        if (c == 'I')
            inserare (root, x - 1, y, ra ());

        if (c == 'A')
            printf ("%d\n", fin (root, x));

        if (c == 'R')
        {
            treap *t1, *t2, *t3, *aux;
            aux = new treap;

            split (root, x, t1, aux);
            split (aux, y + 1, t2, t3);

            t2->inv ^= 1;

            join (aux, t1, t2);
            join (root, aux, t3);
        }

        if (c == 'D')
        {
            treap *t1, *t2, *t3, *aux;

            split (root, x, t1, aux);
            split (aux, y + 1, t2, t3);

            join (root, t1, t3);
        }
    }

    scrie (root);

    return 0;
}