Cod sursa(job #2274171)

Utilizator HumikoPostu Alexandru Humiko Data 1 noiembrie 2018 15:05:58
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.91 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("secv8.in");
ofstream fout ("secv8.out");

class TREAP
{
    public:

        struct treap
        {
            treap *left_Son;
            treap *right_Son;
            int position;
            int value;
            int weight;
            bool propagate;

            treap ( treap *left_Son, treap *right_Son, int position, int value, int weight, bool propagate )
            {
                this->left_Son = left_Son;
                this->right_Son = right_Son;
                this->position = position;
                this->value = value;
                this->weight = weight;
                this->propagate = propagate;
            }
        };

        treap *root, *NILL;

        TREAP ()
        {
            srand(time(NULL));
            NILL = new treap(NULL, NULL, 0, 0, 0, false);
            root = NILL;
        }

        void update ( treap *&node )
        {
            if ( node == NILL )
                return;

            node->position = node->left_Son->position+node->right_Son->position+1;
        }

        void rotateLeftNode ( treap *&node )
        {
            treap *aux;
            aux = node->left_Son;
            node->left_Son = aux->right_Son;
            aux->right_Son = node;

            update (node);
            update (aux);

            node = aux;
        }

        void rotateRightNode ( treap *&node )
        {
            treap *aux;
            aux = node->right_Son;
            node->right_Son = aux->left_Son;
            aux->left_Son = node;

            update(node);
            update(aux);

            node = aux;
        }

        void balance ( treap *&node )
        {
            if ( node->left_Son != NILL && node->left_Son->weight > node->weight )
                rotateLeftNode(node);
            if ( node->right_Son != NILL && node->right_Son->weight > node->weight )
                rotateRightNode(node);

            update(node);
        }

        void propagate( treap *&node )
        {
            if ( node == NILL )
                return;
            if ( node->propagate == false )
                return;

            node->propagate ^= 1;
            swap(node->left_Son, node->right_Son);

            if (node->left_Son != NILL )
                node->left_Son->propagate ^= 1;

            if ( node->right_Son != NILL )
                node->right_Son->propagate ^= 1;
        }

        void insertNode ( treap *&node, int value, int position, int weight )
        {
            if ( node == NILL )
            {
                node = new treap(NILL, NILL, 1, value, weight, false);
                return;
            }

            propagate(node);

            if ( node->left_Son->position+1 >= position )
                insertNode(node->left_Son, value, position, weight);
            else
                insertNode(node->right_Son, value, position-node->left_Son->position-1, weight);

            balance(node);
        }

        int accesPosition ( treap *&node, int position )
        {
            if ( node == NILL )
                return -1;

            propagate(node);

            if ( node->left_Son->position+1 == position )
                return node->value;

            if ( node->left_Son->position >= position )
                return accesPosition(node->left_Son, position);
            else
                return accesPosition(node->right_Son, position-node->left_Son->position-1);
        }

        void eraseNode ( treap *&node )
        {
            if ( node == NILL )
                return;

            propagate(node);

            if ( node->left_Son == NILL && node->right_Son == NILL )
            {
                delete node;
                node = NILL;
                return;
            }

            if ( node->left_Son->weight > node->right_Son->weight )
            {
                propagate(node->left_Son);
                rotateLeftNode(node);
                eraseNode(node->right_Son);
            }
            else
            {
                propagate(node->right_Son);
                rotateRightNode(node);
                eraseNode(node->left_Son);
            }

            update(node);

        }

        void split ( int position, treap *&first, treap *&second )
        {
            insertNode(root, 0, position, 1e8);

            first = root->left_Son;
            second = root->right_Son;

            delete root;
        }

        void reunite ( treap *&first, treap *&second )
        {
            root = new treap(first, second, 0, 0, 1e8, false);
            //propagate(node);
            eraseNode(root);
        }

        void reverseInterval ( treap *&node, int i, int j )
        {
            treap *left, *right;

            split(j+1, left, right);
            root = left;

            treap *LEFT, *RIGHT;

            split(i, LEFT, RIGHT);
            RIGHT->propagate ^= 1;

            reunite(LEFT, RIGHT);
            reunite(root, right);
        }

        void eraseTreap( treap *&node )
        {
            if ( node == NILL )
            {
                node = NULL;
                return;
            }

            eraseTreap(node->left_Son);
            eraseTreap(node->right_Son);

            node = NULL;
        }

        void eraseInterval ( treap *&node, int i, int j )
        {
            treap *left, *right;

            split(j+1, left, right);
            root = left;

            treap *LEFT, *RIGHT;

            split(i, LEFT, RIGHT);

            eraseTreap(RIGHT);

            reunite(LEFT, right);
        }

        void displayInterval ( treap *&node )
        {
            if ( node == NILL )
                return;

            propagate(node);

            displayInterval(node->left_Son);
            fout<<node->value<<" ";
            displayInterval(node->right_Son);
        }
};

char ch;
int operations, is_Reverse, x, y;
TREAP trp;

int main()
{
    ios::sync_with_stdio(false);
    fin.tie(0); fout.tie(0);

    TREAP *trp = new TREAP();

    fin>>operations>>is_Reverse;
    for ( int i = 1; i <= operations; ++i )
    {
        fin>>ch;

        switch( ch )
        {
            case 'I':
                fin>>x>>y;
                trp->insertNode(trp->root, y, x, rand()%666013+1);
                break;

            case 'A':
                fin>>x;
                fout<<trp->accesPosition(trp->root, x)<<'\n';
                break;

            case 'R':
                fin>>x>>y;
                trp->reverseInterval(trp->root, x, y);
                break;

            case 'D':
                fin>>x>>y;
                trp->eraseInterval(trp->root, x, y);
                break;
        }
    }

    trp->displayInterval(trp->root);
}