Cod sursa(job #2256163)

Utilizator Alex18maiAlex Enache Alex18mai Data 8 octombrie 2018 09:08:36
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.37 kb
//ALEX ENACHE

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <cmath>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>
#include <chrono>

using namespace std;

//#include <iostream>

#include <fstream>
ifstream cin ("secv8.in");ofstream cout ("secv8.out");

struct nod {

    //key = nr pe care il tine
    //priority = prioritatea
    //cont = cate noduri sunt in subarborele lui (inclusiv el)
    //lazy = daca treduie sa dau swap la left si right sau nu

    int key , priority , cont , lazy;
    nod *left , *right;

    nod (int key , int priority , int cont , int lazy , nod *left , nod *right){
        this -> key = key;
        this -> priority = priority;
        this -> cont = cont;
        this -> lazy = lazy;

        this -> left = left;
        this -> right = right;
    }
};

nod *nil , *root;

const int limit = 1e9;

void init(){
    nil = new nod(-1 , 0 , 0 , 0 , NULL , NULL);
    root = nil;
}

void update(nod *&now){
    if (now == nil){
        return;
    }
    now -> cont = now -> left -> cont + now -> right -> cont + 1;
}

void propagate(nod *&now){
    if (now == nil || ! now -> lazy){
        return;
    }

    now -> lazy ^= 1;
    swap (now -> left , now -> right);
    if (now -> left != nil){
        now -> left -> lazy ^= 1;
    }
    if (now -> right != nil){
        now -> right -> lazy ^= 1;
    }
}

void rotleft(nod *&now){
    nod *aux = now -> left;
    now -> left = aux -> right;
    aux -> right = now;

    update(now);
    update(aux);
    now = aux;
}

void rotright(nod *&now){
    nod *aux = now -> right;
    now -> right = aux -> left;
    aux -> left = now;

    update(now);
    update(aux);
    now = aux;
}

void balance(nod *&now){
    if (now -> priority < now -> left -> priority){
        rotleft(now);
    }
    if (now -> priority < now -> right -> priority){
        rotright(now);
    }
    update(now);
}

void insert(nod *&now , int key , int priority , int poz){
    if (now == nil){
        now = new nod(key , priority , 1 , 0 , nil , nil);
        return;
    }

    propagate(now);

    if (now -> left -> cont + 1 >= poz){
        insert(now -> left , key , priority , poz);
    }
    else{
        insert(now -> right , key , priority , poz - now -> left -> cont - 1);
    }

    balance(now);
}

void erase(nod *&now ){
    if (now == nil){
        return;
    }

    propagate(now);

    if (now -> left == nil && now -> right == nil){
        delete now;
        now = nil;
        return;
    }
    if (now -> left -> priority > now -> right -> priority){
        propagate(now -> left);
        rotleft(now);
        erase(now -> right);
    }
    else{
        propagate(now -> right);
        rotright(now);
        erase(now -> left);
    }
    update(now);
}

void search(nod *&now , int poz){
    if (now == nil){
        return;
    }

    propagate(now);

    if (now -> left -> cont + 1 == poz){
        cout<<now -> key<<'\n';
        return;
    }
    if (now -> left -> cont >= poz){
        search(now -> left , poz);
    }
    else{
        search(now -> right , poz - now -> left -> cont - 1);
    }
}

void split(int poz , nod *&st , nod *&dr){
    insert(root , 0 , limit , poz);
    st = root -> left;
    dr = root -> right;
    delete root;
}

void join(nod *&st , nod *&dr){
    root = new nod(0 , limit , 0 , 0 , st , dr);
    erase (root);
}

void reverse(int st , int dr){
    nod *l , *r;
    split(dr+1 , l , r);
    root = l;
    nod *L , *R;
    split(st , L , R);

    R -> lazy ^= 1;

    join(L , R);
    join(root , r);
}

void clear(nod *&now){
    if (now == nil){
        now = NULL;
        return;
    }
    clear(now -> left);
    clear(now -> right);
    delete now;
}

void remove(int st , int dr){
    nod *l , *r;
    split(dr+1 , l , r);
    root = l;
    nod *L , *R;
    split(st , L , R);

    clear(R);
    join(L , r);
}

void afis(nod *&now){
    if (now == nil){
        return;
    }

    propagate(now);

    afis(now -> left);
    //cout<<now -> key<<" "<<now -> cont<<" "<<now -> left -> cont<<" "<<now -> right -> cont<<'\n';
    cout<<now -> key<<" ";
    afis(now -> right);
}

int main() {

    //freopen("input", "r", stdin);freopen("output", "w", stdout);

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    srand(time(NULL));
    init();

    int n , penal;
    cin>>n>>penal;

    for (int i=1; i<=n; i++){
        string s;
        cin>>s;

        if (s == "I"){
            int val , poz;
            cin>>poz>>val;

            insert(root , val , rand() % (limit - 1) + 1 , poz);
        }

        if (s == "A"){
            int val;
            cin>>val;

            search(root , val);
        }

        if (s == "R"){
            int st , dr;
            cin>>st>>dr;

            reverse(st , dr);
        }

        if (s == "D"){
            int st , dr;
            cin>>st>>dr;

            remove(st , dr);
        }

        /*cout<<i<<" : "<<'\n';
        cout<<'\n';
        afis(root);
        cout<<'\n';*/
    }

    afis(root);

    return 0;
}