Cod sursa(job #1674882)

Utilizator ZenusTudor Costin Razvan Zenus Data 4 aprilie 2016 22:05:00
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.54 kb
#include <bits/stdc++.h>

using namespace std;

const int mod = 1000000000;

int n , p , i , j , x , k;
char t;

struct iTreap
{
    iTreap *left , *right;
    int reversed , weight , value , priority;

    iTreap(int weight0 , int value0 , iTreap *left0 , iTreap *right0 , int p0)
    {
        reversed = 0;
        weight = weight0;
        value = value0;
        priority = p0;
        left = left0;
        right = right0;
    }
} *nil , *root , *Lroot , *Rroot;

class Treap
{
    private :
    void runReverse(iTreap *(&root))
    {
        if (root -> reversed)
        {
            swap(root -> left , root -> right);
            root -> reversed = 0;
            root -> left -> reversed = 1 - root -> left -> reversed;
            root -> right -> reversed = 1 - root -> right -> reversed;
        }
    }

    void runWeight(iTreap *(&root))
    {
        root -> weight = root -> left -> weight + root -> right -> weight + 1;
    }

    void rotateRight(iTreap *(&root))
    {
        iTreap *R = root -> left;
        root -> left = R -> right;
        R -> right = root;
        root = R;

        runWeight(root -> right);
        runWeight(root);
    }

    void rotateLeft(iTreap *(&root))
    {
        iTreap *R = root -> right;
        root -> right = R -> left;
        R -> left = root;
        root = R;

        runWeight(root -> left);
        runWeight(root);
    }

    void balance(iTreap *(&root))
    {
        if (root -> left -> priority > root -> priority)
        {
            runReverse(root);
            runReverse(root -> left);
            rotateRight(root);
        }
        else if (root -> right -> priority > root -> priority)
        {
            runReverse(root);
            runReverse(root -> right);
            rotateLeft(root);
        }
    }

    public :

    void insert(iTreap *(&root) , int k , int x , int p)
    {
        if (root == nil)
        {
            root = new iTreap(1 , x , nil , nil , p);
            return ;
        }

        runReverse(root);

        if (k <= 1 + root -> left -> weight)
        insert(root -> left , k , x , p);
        else insert(root -> right , k - (1 + root -> left -> weight) , x , p);

        runWeight(root);
        balance(root);
    }

    void erase(iTreap *(&root) , int k)
    {
        runReverse(root);

        if (1 + root -> left -> weight > k)
        {
            erase(root -> left , k);
            runWeight(root);
            return ;
        }

        if (1 + root -> left -> weight < k)
        {
            erase(root -> right , k - (1 + root -> left -> weight));
            runWeight(root);
            return ;
        }

        if (root -> left == nil && root -> right == nil)
        {
            root = nil;
            return ;
        }

        if (root -> left -> priority > root -> right -> priority)
        {
            runReverse(root -> left);
            rotateRight(root);
            erase(root -> right , 1 + root -> right -> left -> weight);
            runWeight(root);
        }
        else
        {
            runReverse(root -> right);
            rotateLeft(root);
            erase(root -> left , 1 + root -> left -> left -> weight);
            runWeight(root);
        }
    }

    int show(iTreap *root , int k)
    {
        runReverse(root);
        if (1 + root -> left -> weight == k) return root -> value;
        if (k < 1 + root -> left -> weight) return show(root -> left , k);
        else return show(root -> right , k - (1 + root -> left -> weight));
    }

    void split(iTreap *root , int k , iTreap *(&Lroot) , iTreap *(&Rroot))
    {
        insert(root , k + 1 , 0 , mod + 1);
        Lroot = root -> left;
        Rroot = root -> right;
        delete root;
    }

    void join(iTreap *(&root) , iTreap *Lroot , iTreap *Rroot)
    {
        if (Lroot == nil)
        {
            root = Rroot;
            return;
        }

        if (Rroot == nil)
        {
            root = Lroot;
            return ;
        }

        runReverse(Lroot);
        runReverse(Rroot);

        root = new iTreap(1 + Lroot -> weight + Rroot -> weight , 0 , Lroot , Rroot , 0);
        erase(root , 1 + Lroot -> weight);
    }

    void go(iTreap *root)
    {
        if (root == nil) return ;

        runReverse(root);
        go(root -> left);
        printf("%d " , root -> value);
        go(root -> right);
    }

} T;

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

nil = new iTreap(0 , 0 , 0 , 0 , 0);
root = nil;

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

for ( ; n ; --n)
{
    scanf("\n%c" , &t);

    if (t == 'I')
    {
        scanf("%d" , &k);
        scanf("%d" , &x);

        p = rand() % mod + 1;
        T.insert(root , k , x , p);
    }

    if (t == 'A')
    {
        scanf("%d" , &k);
        printf("%d\n" , T.show(root , k));
    }

    if (t == 'D')
    {
        scanf("%d" , &i);
        scanf("%d" , &j);

        T.split(root , i - 1 , Lroot , root);
        T.split(root , j - i + 1 , root , Rroot);

        T.join(root , Lroot , Rroot);
    }

    if (t == 'R')
    {
        scanf("%d" , &i);
        scanf("%d" , &j);

        T.split(root , i - 1 , Lroot , root);
        T.split(root , j - i + 1 , root , Rroot);

        root -> reversed = 1 - root -> reversed;

        T.join(root , Lroot , root);
        T.join(root , root , Rroot);
    }
}

T.go(root);

return 0;
}