Cod sursa(job #2540683)

Utilizator Briana_NeaguNeagu Briana Briana_Neagu Data 7 februarie 2020 14:52:50
Problema Secv8 Scor 25
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.64 kb
#include <bits/stdc++.h>

using namespace std;

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

const int inf = 1e9 + 5;
class Treap
{
public:
    struct Node
    {
        int key;
        int priority;
        int cnt;
        int lazy;
        Node* leftSon;
        Node* rightSon;
        Node(): key(0), priority(0), cnt(0), lazy(0), leftSon(nullptr), rightSon(nullptr){};
        Node(int _key, int _prio, Node* _nill) : key(_key), priority(_prio), cnt(1), lazy(0), leftSon(_nill), rightSon(_nill){};

    };
    Node* root;
    Node* Nill;
    Treap()
    {
        srand(time(NULL));
        Nill = new Node();
        Nill -> leftSon = Nill;
        Nill -> rightSon = Nill;
        root = Nill;
    }

    void insert(int val, int poz)
    {
        int priority = rand() % (inf - 1) + 1;
       private_insert(root, poz, val, priority);
      // g << "root : " <<  root -> key << " " << root -> cnt << '\n';
    }

    int acces(int poz)
    {
       return private_acces(root, poz);
    }

    void reverse(int i, int j)
    {
        private_insert(root, j + 1, j + 1, inf);
        Node* rootRight = root -> leftSon; // intervalul 1 - j
        //Node* aux = rootRight;
        private_insert(rootRight, i, 0, inf);
        Node* rootLeft  = rootRight -> rightSon; // aici am intervalul i, j
        rootLeft -> lazy = rootLeft -> lazy ^ 1;
        private_erase(rootRight, i);
        private_erase(root, j + 1);
    }

    void remove(int i, int j)
    {
       private_insert(root, j + 1, j + 1, inf);
       Node* goodRight = root -> rightSon; // j + 1, n
      // g << goodRight -> key << '\n' ;
       Node *badBig = root -> leftSon; // 1, j
       private_insert(badBig, i, 0, inf);
        Node* goodLeft = badBig -> leftSon; // 1 , i - 1
      // g << goodLeft -> key <<'\n';
       root -> leftSon = goodLeft;
       root -> rightSon = goodRight;
       update(root);
       private_erase(root, j + 1);
    }
    void show()
    {
        private_show(root);
    }

private:

    void propagate(Node*& node)
    {
        assert(node -> lazy);
        swap(node -> leftSon, node -> rightSon);
        node -> leftSon -> lazy ^= 1;
        node -> rightSon -> lazy ^= 1;
        node -> lazy = 0;
    }

    void update(Node*& node)
    {
       node -> cnt = node -> leftSon -> cnt + node -> rightSon -> cnt + 1;//si pe el
    }
    void rotateLeft(Node*& toChange)
    {
        Node* newNode = toChange -> leftSon;
        toChange -> leftSon = newNode -> rightSon;
        newNode -> rightSon = toChange;
        update(toChange);
        toChange = newNode;
    }

    void rotateRight(Node*& toChange)
    {
        Node* newNode = toChange -> rightSon;
        toChange -> rightSon = newNode -> leftSon;
        newNode -> leftSon =  toChange;
        update(toChange);
        toChange = newNode;
    }

    void balance(Node*& node)
    {
        if (node -> leftSon -> priority > node -> priority)
            rotateLeft(node);
        else if (node -> rightSon -> priority > node -> priority)
            rotateRight(node);
    }
    void private_insert(Node*& node, int poz, const int value, const int priority)
    {
        if (node == Nill)
        {
            node = new Node(value, priority, Nill);
            return;
        }
        if (node -> lazy)
            propagate(node);
        if (node -> leftSon -> cnt + 1 >= poz)
            private_insert(node -> leftSon, poz, value, priority);
        else
            private_insert(node -> rightSon, poz - node -> leftSon -> cnt -1, value, priority);
        balance(node);
        update(node);
    }

    int private_acces(Node*& node, int poz)
    {
        if (node -> lazy)
            propagate(node);
        if (node -> cnt - node -> rightSon -> cnt == poz) // daca inainte sunt poz - 1, l am gasit
        {
            return node -> key;
        }
       if (node -> leftSon -> cnt >= poz)
           return private_acces(node -> leftSon, poz);
       else
           return private_acces(node -> rightSon, poz - node -> leftSon -> cnt - 1);
    }

    void private_erase(Node*& node, int key)
    {
        if (node -> lazy)
            propagate(node);
        if (node -> leftSon == Nill && node -> rightSon == Nill)
        {
            delete node;
            node = Nill;
            return;
        }
        if (node -> leftSon -> priority > node -> rightSon -> priority)
        {
            if (node -> leftSon -> lazy)
                propagate(node -> leftSon);
            rotateLeft(node);
            private_erase(node -> rightSon, key);
        }
        else
        {
           if (node -> rightSon -> lazy)
               propagate(node -> rightSon);
            rotateRight(node);
            private_erase(node -> leftSon,  key);
        }
        update(node);
    }

    void private_show(Node*& node)
    {
        if (node -> leftSon != Nill)
            private_show(node -> leftSon);
        g << node -> key << " ";
        if (node -> rightSon != Nill)
            private_show(node -> rightSon);
    }
};



int main()
{
    int n, dc;
    f  >> n >> dc;
    auto *treap = new Treap();
    while (n --)
    {
        char op;
        f >> op;
        if (op == 'I')
        {
            int val, poz;
            f >> poz >> val;
            treap -> insert(val, poz);
        }
        else if (op == 'A')
        {
            int poz;
            f >> poz;
            g <<  treap -> acces(poz) << '\n';

        }
        else  if (op == 'R')
        {

            int i, j;
            f >> i >> j;
            treap -> reverse(i, j);
        }
        else
        {
            assert(op == 'D');
            int i, j;
            f >> i >> j;
            treap -> remove(i, j);
        }
    }
    treap -> show();
}