Cod sursa(job #2472559)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 12 octombrie 2019 16:28:36
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.27 kb
#include <fstream>
#include <cstdlib>
using namespace std;
ifstream f("secv8.in");
ofstream g("secv8.out");
int N, cnt;
const int INF = 1000000007;
struct Node{
    int sz, val, rev, priority;
    Node* left, *right;
    Node(int sz, int priority, int val, int rev, Node* left, Node* right){
        this -> sz = sz;
        this -> val = val;
        this -> priority = priority;
        this -> rev = rev;
        this -> left = left;
        this -> right = right;
    }
} *Root, *nullNode;

void init(){
    Root = nullNode = new Node(0, 0, 0, 0, NULL, NULL);
}

void rotateLeft(Node*& node){
    Node* aux = node -> left;
    node -> left = aux -> right;
    aux -> right = node;
    node = aux;
}

void rotateRight(Node*& node){
    Node* aux = node -> right;
    node -> right = aux -> left;
    aux -> left = node;
    node = aux;
}
void update(Node*& node){

    node -> sz = node -> left -> sz + node -> right -> sz + 1;
}
void push(Node*& node, int depth){
    if(node -> rev == 1){
        swap(node -> left, node -> right);
        if(node -> left)
            node -> left -> rev ^= 1;
        if(node -> right)
            node -> right -> rev ^= 1;
    }
    node ->rev = 0;
    if(depth == 1)
        return;
    if(node -> left)
        push(node -> left, depth - 1);
    if(node -> right)
        push(node -> right, depth - 1);
}
void balance(Node*& node){
    int who = 0;
    if(node -> left -> priority < node -> right -> priority)
        who = 1;
    if(who == 0){
        if(node -> left -> priority > node -> priority){
            rotateLeft(node);
            update(node -> right);
        }

    }

    if(who == 1)
        if(node -> right -> priority > node -> priority){
            rotateRight(node);
            update(node -> left);
        }


}


int getRand(){
    return (1LL * rand() * rand()) % INF;
}
void insertElement(Node*& node, int value, int position, int priority){

    if(node == nullNode){
        node = new Node(1, priority, value, 0, nullNode, nullNode);
        return;
    }
    update(node);
    push(node, 2);
    if(position >= node -> left -> sz + 1)
        insertElement(node -> right, value, position - node -> left -> sz - 1, priority);
    else
        insertElement(node -> left, value, position, priority);
    balance(node);
    update(node);
}

void eraseElement(Node*& node, int position, bool del){
    //update(node);
    if(node == nullNode)
        return;
    update(node);
    push(node, 2);
    if(!del){
        if(node -> left -> sz == position){
            eraseElement(node, 0, 1);
            return;
        }
        if(node -> left -> sz + 1 < position)
            eraseElement(node -> right, position - node -> left -> sz - 1, 0);
        else
            eraseElement(node -> left, position, 0);
    }
    if(del){
        if(node -> left == nullNode && node -> right == nullNode){
            delete node, node = nullNode;
            return;
        }
        if(node -> left -> priority > node -> right -> priority){
            rotateLeft(node);
            eraseElement(node -> right, position, 1);
        }
        else{

            rotateRight(node);
            eraseElement(node -> left, position, 1);
        }


    }
    update(node);
}

void split(int position, Node*& Root, Node*& left, Node*& right){
    //--position;
    insertElement(Root, 0, position, INF);
    left = Root -> left;
    right = Root -> right;
    delete Root;
    Root = nullNode;
}

void join(Node*& Root, Node*& left, Node*& right){
    Root = new Node(left -> sz + right -> sz + 1, INF, 0, 0, left, right);
    eraseElement(Root, left -> sz, 0 );
}

int accessElement(Node*& node, int position){
    push(node, 2);
    if(node -> left -> sz == position)
        return node -> val;
    if(node -> left -> sz + 1 <= position)
        return accessElement(node -> right, position - node -> left -> sz - 1);
    if(node -> left -> sz > position)
        return accessElement(node -> left, position);
}

void eraseRange(int left, int right){
    Node* T1, *T2, *T3, *T4;
    split(left - 1, Root, T1, T2);
    split(right - left + 1, T2, T3, T4);
    //int res = T4 -> val;
    join(Root, T1, T4);
    //join(Root, T1, T2);
}

void reverseRange(int left, int right){
    Node* T1, *T2, *T3, *T4;
    split(left - 1, Root, T1, T2);
    split(right - left + 1, T2, T3, T4);
    //int res = T4 -> val;
    T3 -> rev ^= 1;
    join(T2, T3, T4);
    join(Root, T1, T2);
}

void printArray(){
    for(int i = 1; i <= Root -> sz; i++)
        g << accessElement(Root, i - 1) << ' ';
    g << '\n';
}
void Solve(){
    int N, r;
    f >> N >> r;
    for(int i = 1; i <= N; i++){
        char ch;
        f >> ch;
        int x, y;
        if(ch == 'I'){
            f >> x >> y;
            insertElement(Root, y, x - 1, getRand());
        }
        if(ch == 'A'){
            f >> x;
            g << accessElement(Root, x - 1) << '\n';
        }
        if(ch == 'R'){
            f >> x >> y;
            reverseRange(x, y);
        }
        if(ch == 'D'){
            f >> x >> y;
            eraseRange(x, y);
        }

    }
    printArray();
}
int main()
{
    init();
    Solve();
    return 0;
}