Cod sursa(job #2272191)

Utilizator giotoPopescu Ioan gioto Data 29 octombrie 2018 20:06:15
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <bits/stdc++.h>
using namespace std;

struct item{
    long long prior;
    int k, w;
    bool rev;
    item *l, *r;
    item(){
        prior = k = w = rev = 0;
        l = NULL; r = NULL;
    }
};
typedef item * pitem;

void push(pitem &it){
    if(it && it->rev){
        it->rev = 0;
        swap(it->l, it->r);
        if(it->l) it->l->rev ^= 1;
        if(it->r) it->r->rev ^= 1;
    }
}
int get_val(pitem it){
    if(it) return it->k;
    return 0;
}
void upd_val(pitem &it){
    if(it) {
        it->k = get_val(it->l) + get_val(it->r) + 1;
        bool ok = 0;
    }
}

void split(pitem &t, pitem &l, pitem &r, int key, int aux){
    if(!t){
        l = r = 0;
        return ;
    }
    push(t);
    int cur_key = aux + get_val(t->l);
    if(key <= cur_key)
        split(t->l, l, t->l, key, aux), r = t;
    else
        split(t->r, t->r, r, key, aux + 1 + get_val(t->l)), l = t;
    upd_val(t);
}

void merge(pitem &t, pitem &l, pitem &r){
    push(l);
    push(r);
    if(!l || !r)
        t = l ? l : r;
    else if(l->prior > r->prior){
        merge(l->r, l->r, r);
        t = l;
    }
    else{
        merge(r->l, l, r->l);
        t = r;
    }
    upd_val(t);
}

void insert(pitem &t, int w, int key, long long prior){
    push(t);
    pitem t1 = new item, t2 = new item;
    pitem it = new item;
    it->w = w; it->prior = prior; it->k = 1;
    split(t, t1, t2, key - 1, 0);
    merge(t1, t1, it);
    merge(t, t1, t2);
}

void erase(pitem &t, int l, int r){
    push(t);
    pitem t1 = new item, t2 = new item, t3 = new item;
    split(t, t1, t2, l - 1, 0);
    split(t2, t2, t3, r - l + 1, 0);
    merge(t, t1, t3);
}

void reverse(pitem &t, int l, int r){
    pitem t1 = new item, t2 = new item, t3 = new item;
    split(t, t1, t2, l - 1, 0);
    split(t2, t2, t3, r - l + 1, 0);

    if(t2) t2->rev ^= 1;

    merge(t, t1, t2);
    merge(t, t, t3);
}

int acces(pitem t, int key, int aux){
    push(t);

    int cur_key = aux + get_val(t->l);
    if(cur_key + 1 == key) return t->w;
    else if(cur_key >= key) return acces(t->l, key, aux);
    else return acces(t->r, key, aux + get_val(t->l) + 1);
}

void output(pitem t){
    if(!t) return ;
    push(t);
    output(t->l);
    printf("%d ", t->w);
    output(t->r);
}

pitem t;
int main()
{
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);

    bool ok;
    int n, x, y;
    char c;

    srand(time(NULL));

    scanf("%d%d\n", &n, &ok);
    while(n--){
        scanf("%c", &c);
        if(c == 'I'){
            scanf("%d%d\n", &y, &x);

            long long pr = 0;
            for(int i = 0; i <= 58 ; i += 2)
                pr = pr + 1LL * (rand() % 4) * (1LL << i);

            insert(t, x, y, pr);
        }
        else if(c == 'A'){
            scanf("%d\n", &x);
            printf("%d\n", acces(t, x, 0));
        }
        else if(c == 'R'){
            scanf("%d%d\n", &x, &y);
            reverse(t, x, y);
        }
        else if(c == 'D'){
            scanf("%d%d\n", &x, &y);
            erase(t, x, y);
        }
    }
    output(t);

    return 0;
}