Cod sursa(job #2629741)

Utilizator Senth30Denis-Florin Cringanu Senth30 Data 22 iunie 2020 15:45:57
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.95 kb
#include <bits/stdc++.h>
#define MAX 131072
#define MOD 1000000007

using namespace std;
const int INF = (int)2147483647;

struct Treap{
    int priority, val, tsize;
    bool lazy;
    Treap *left, *right;
    Treap(int p, int x){
        left = right = NULL;
        priority = p;
        val = x;
        tsize = 1;
        lazy = false;
    }
};

int Q;
int xVal, pos, prir, A, B;

Treap* root = NULL;

inline int good_rand() {
    return (rand() << 15) | rand();
}

inline void solve_lazy(Treap *node){
    if(node == NULL)
        return;
    if(node->lazy){
        swap(node->left, node->right);
        if(node->left != NULL)
            node->left->lazy ^= 1;
        if(node->right != NULL)
            node->right->lazy ^= 1;
    }
    node->lazy = 0;
}

inline void tRefresh(Treap* node){
    node->tsize = 1;
    if(node->left != NULL)
        node->tsize += node->left->tsize;
    if(node->right != NULL)
        node->tsize += node->right->tsize;
}

inline Treap* tRotRight(Treap* node){
    solve_lazy(node);
    Treap* aux = node->right;
    solve_lazy(aux);
    node->right = aux->left;
    aux->left = node;
    tRefresh(node);
    tRefresh(aux);
    return aux;
}

inline Treap* tRotLeft(Treap* node){
    solve_lazy(node);
    Treap* aux = node->left;
    solve_lazy(aux);
    node->left = aux->right;
    aux->right = node;
    tRefresh(node);
    tRefresh(aux);
    return aux;
}

inline Treap* tBalance(Treap* node){
    solve_lazy(node);
    if(node->left != NULL && node->priority < node->left->priority)
        return tRotLeft(node);
    if(node->right != NULL && node->priority < node->right->priority)
        return tRotRight(node);
    tRefresh(node);
    return node;
}

Treap* tInsert(Treap* node){
    solve_lazy(node);
    if(node == NULL){
        node = new Treap(prir, xVal);
        return node;
    }
    if(node->left == NULL){
        if(pos > 0){
            --pos;
            node->right = tInsert(node->right);
        } else node->left = tInsert(node->left);
    } else {
        if(pos > node->left->tsize){
            pos -= node->left->tsize + 1;
            node->right = tInsert(node->right);
        } else node->left = tInsert(node->left);
    }
    return tBalance(node);
}

int tAccess(Treap* node){
    solve_lazy(node);
    if((node->left == NULL && pos == 1) || (node->left != NULL && pos == node->left->tsize + 1))
        return node->val;
    else{
        if(node->left == NULL){
            --pos;
            return tAccess(node->right);
        }
        if(pos > node->left->tsize){
            pos -= node->left->tsize + 1;
            return tAccess(node->right);
        } else return tAccess(node->left);
    }
}

Treap* tErase(Treap* node, int poz, bool flag){
    solve_lazy(node);
    if((poz == 1 && node->left == NULL) || (node->left != NULL && poz == node->left->tsize + 1) || flag){
        Treap* aux;
        if(node->left == NULL && node->right == NULL){
            delete node;
            return NULL;
        } else if(node->left == NULL){
            aux = tRotRight(node);
            aux->left = tErase(aux->left, poz, 1);
        } else if(node->right == NULL){
            aux = tRotLeft(node);
            aux->right = tErase(aux->right, poz, 1);
        } else if(node->left->priority > node->right->priority){
            aux = tRotRight(node);
            aux->left = tErase(aux->left, poz, 1);
        } else {
            aux = tRotLeft(node);
            aux->right = tErase(aux->right, poz, 1);
        }
        return tBalance(aux);
    } else {
        if(node->left == NULL)
            node->left = tErase(node->left, poz, 0);
        else{
            if(node->left->tsize >= poz)
                node->left = tErase(node->left, poz, 0);
            else node->right = tErase(node->right, poz - node->left->tsize - 1, 0);
        }
        return tBalance(node);
    }
}

inline pair <Treap*, Treap*> tSplit(Treap* node){
    solve_lazy(node);
    Treap* aux = tInsert(node);
    return {aux->left, aux->right};
}

inline Treap* tJoin(pair <Treap*, Treap*> node){
    solve_lazy(node.first);
    solve_lazy(node.second);
    Treap* aux = new Treap(INF, 0);
    aux->left = node.first;
    aux->right = node.second;
    if(aux->left == NULL)
        aux = tErase(aux, 1, 0);
    else aux = tErase(aux, aux->left->tsize + 1, 0);
}

inline Treap* tDelete(Treap* node){
    solve_lazy(node);
    pos = A - 1; xVal = 0; prir = INF;
    pair <Treap*, Treap*> aux1 = tSplit(node);
    pos = B - A + 1; xVal = 0; prir = INF;
    pair <Treap*, Treap*> aux2 = tSplit(aux1.second);
    return tJoin({aux1.first, aux2.second});
}

inline Treap *tReverse(Treap *node){
    solve_lazy(node);
    pos = A - 1; xVal = 0; prir = INF;
    pair <Treap*, Treap*> aux1 = tSplit(node);
    pos = B - A + 1; xVal = 0; prir = INF;
    pair <Treap*, Treap*> aux2 = tSplit(aux1.second);
    if(aux2.first != NULL)
        aux2.first->lazy ^= 1;
    return tJoin({tJoin({aux1.first, aux2.first}), aux2.second});
}

inline void tShow(Treap *node){
    if(node->left != NULL)
        tShow(node->left);
    printf("%d ", node->val);
    if(node->right != NULL)
        tShow(node->right);
}

int main(){

    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    srand(time(NULL));

    char ch;
    scanf("%d %c ", &Q, &ch);
    for(; Q; --Q){
        scanf("%c", &ch);
        if(ch == 'I'){
            prir = good_rand();
            scanf("%d%d ", &pos, &xVal);
            pos--;
            root = tInsert(root);
        } else if(ch == 'A'){
            scanf("%d ", &pos);
            printf("%d\n", tAccess(root));
        } else if(ch == 'D'){
            scanf("%d%d ", &A, &B);
            root = tDelete(root);
        } else {
            scanf("%d%d ", &A, &B);
            root = tReverse(root);
        }
    }
    tShow(root);

    return 0;
}