Cod sursa(job #2701033)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 29 ianuarie 2021 17:03:00
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.46 kb
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int MOD = 1000000007;

struct Node{
    int priority, cnt, rev, value;
    Node* left, *right;
    Node(int priority, int value, Node* left, Node* right){
        this -> priority = priority;
        this -> value = value;
        this -> left = left;
        this -> right = right;
        this -> cnt = 1;
        this -> rev = 0;
    }
};
int Q;
typedef Node* Nodep;

int getCnt(Nodep node){
    if(node == NULL)
        return 0;
    return node -> cnt;
}

void updateCnt(Nodep node){
    if(node == NULL)
        return;
    node -> cnt = getCnt(node -> left) + getCnt(node -> right) + 1;
}

void pushRev(Nodep node){
    if(node == NULL || node -> rev == 0)
        return;
    swap(node -> left, node -> right);
    if(node -> left)
        node -> left -> rev ^= 1;
    if(node -> right)
        node -> right -> rev ^= 1;
    node -> rev = 0;
}

void split(Nodep tree, int key, Nodep& tree1, Nodep& tree2, int add){
    if(tree == NULL){
        tree1 = tree2 = NULL;
        return;
    }
    pushRev(tree);
    int curr_key = add + getCnt(tree -> left) + 1;
    if(curr_key == key){
        tree1 = tree;
        tree2 = tree -> right;
        tree -> right = NULL;
    }
    else{
        if(curr_key <= key){
            split(tree -> right, key, tree -> right, tree2, add + getCnt(tree -> left) + 1);
            tree1 = tree;
        }
        else{
            split(tree -> left, key, tree1, tree -> left, add);
            tree2 = tree;
        }
    }
    updateCnt(tree);
}

void join(Nodep& result, Nodep tree1, Nodep tree2){
    pushRev(tree1);
    pushRev(tree2);
    if(tree1 == NULL){
        result = tree2;
        return;
    }
    if(tree2 == NULL){
        result = tree1;
        return;
    }
    if(tree1 -> priority > tree2 -> priority){
        join(tree1 -> right, tree1 -> right, tree2);
        result = tree1;
    }
    else{
        join(tree2 -> left, tree1, tree2 -> left);
        result = tree2;
    }
    updateCnt(result);
}

int getRand(){
    return(1LL * rand() * rand()) % MOD;
}

void insert(Nodep& tree, int key, int value){
    Nodep tree1, tree2, tree3;
    split(tree, key - 1, tree1, tree2, 0);
    Nodep newNode = new Node(getRand(), value, NULL, NULL);
    join(tree, tree1, newNode);
    join(tree, tree, tree2);
}

void deleteTree(Nodep tree2){
    if(tree2 == NULL)
        return;
    deleteTree(tree2 -> left);
    deleteTree(tree2 -> right);
}

void erase(Nodep& tree, int left, int right){
    Nodep tree1, tree2, tree3;
    split(tree, left - 1, tree1, tree2, 0);
    split(tree2, (right - left + 1), tree2, tree3, 0);
    join(tree, tree1, tree3);
    deleteTree(tree2);
}

void reverse(Nodep& tree, int left, int right){
    Nodep tree1, tree2, tree3;
    split(tree, left - 1, tree1, tree2, 0);
    split(tree2, (right - left + 1), tree2, tree3, 0);
    tree2 -> rev ^= 1;
    join(tree, tree1, tree2);
    join(tree, tree, tree3);
}

void printRange(Nodep tree){
    if(tree == NULL)
        return;
    pushRev(tree);
    printRange(tree -> left);
    printf("%d ", tree -> value);
    printRange(tree -> right);
}

int get(Nodep tree, int key){
    if(tree == NULL)
        return 0;
    pushRev(tree);
    if(getCnt(tree -> left) + 1 == key)
        return tree -> value;
    if(key > getCnt(tree -> left) + 1)
        return get(tree -> right, key - getCnt(tree -> left) - 1);
    return get(tree -> left, key);
}

void Solve(){
    scanf("%d", &Q);
    int r;
    scanf("%d", &r);

    Nodep root = NULL;
    for(int i = 1; i <= Q; i++){
        char ch;
        scanf("%c", &ch);
        scanf("%c", &ch);
        int x, y;
        if(ch == 'I'){
            scanf("%d%d", &x, &y);
            insert(root, x, y);
            //printRange(root);
            //printf("\n");
        }
        if(ch == 'A'){
            scanf("%d", &x);
            printf("%d\n", get(root, x));
        }
        if(ch == 'R'){
            scanf("%d%d", &x, &y);
            reverse(root, x, y);
            //printRange(root);
            //printf("\n");
        }
        if(ch == 'D'){
            scanf("%d%d", &x, &y);
            erase(root, x, y);
        }
    }
    printRange(root);
    printf("\n");
}

int main()
{
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    Solve();
    return 0;
}