Cod sursa(job #1992643)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 21 iunie 2017 00:10:25
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 kb
#include <bits/stdc++.h>
using namespace std;

const int INF = 0x7FFFFFFF;

struct T {
    int val, siz, pr;
    bool rev;
    T *st, *dr; } nil {0, 0, -1, false, 0x00, 0x00};

void reset(T *a) {
    a->siz = a->st->siz + a->dr->siz + 1; }

void prop(T *a) {
    if(a->rev) {
        a->rev = 0;
        a->st->rev^= 1;
        a->dr->rev^= 1;
        swap(a->st, a->dr); } }

T* join(T *a, T *b) {
    if(a == &nil) return b;
    if(b == &nil) return a;

    prop(a);
    prop(b);

    if(a->pr > b->pr) {
        a->dr = join(a->dr, b);
        reset(a);
        return a; }
    else {
        b->st = join(a, b->st);
        reset(b);
        return b; } }

T* join3(T *a, T *b, T *c) {
    return join(a, join(b, c)); }

pair<T*, T*> split(T *nod, int pos) {
    if(nod == &nil) return make_pair(&nil, &nil);

    prop(nod);

    if(nod->st->siz == pos) {
        T *tmp = nod->st;
        nod->st = &nil;
        reset(nod);
        return make_pair(tmp, nod); }
    if(nod->st->siz > pos) {
        auto tmp = split(nod->st, pos);
        nod->st = tmp.second;
        reset(nod);
        return make_pair(tmp.first, nod); }
    if(nod->st->siz < pos) {
        auto tmp = split(nod->dr, pos-nod->st->siz-1);
        nod->dr = tmp.first;
        reset(nod);
        return make_pair(nod, tmp.second); } }

tuple<T*, T*, T*> split3(T* nod, int x, int y) {
    auto a = split(nod, y);
    auto b = split(a.first, x);
    return make_tuple(b.first, b.second, a.second); }

T* reverse(T *nod, int x, int y) {
    auto tp = split3(nod, x, y);
    get<1>(tp)->rev^= 1;
    return join3(get<0>(tp), get<1>(tp), get<2>(tp)); }

T* insert(T *nod, int pos, int val) {
    auto pr = split(nod, pos);
    return join3(pr.first, new T {val, 1, rand(), false, &nil, &nil}, pr.second); }

T* remove(T *nod, int x, int y) {
    auto tp = split3(nod, x, y);
    return join(get<0>(tp), get<2>(tp)); }

T *kth(T *nod, int pos) {
    prop(nod);

    if(nod->st->siz == pos) return nod;
    if(nod->st->siz > pos) return kth(nod->st, pos);
    if(nod->st->siz < pos) return kth(nod->dr, pos-nod->st->siz-1); }

void dfs(T *nod) {
    if(nod == &nil) return;
    prop(nod);

    dfs(nod->st);
    if(nod->val > 0)
        printf("%d ", nod->val);
    dfs(nod->dr); }

int main(void) {
    freopen("secv8.in",  "r", stdin);
    freopen("secv8.out", "w", stdout);
    int m, val, pos, x, y, junk;
    char op;
    T *root;

    root = &nil;
    srand(time(NULL));

    scanf("%d%d", &m, &junk);
    while(m--) {
        scanf(" %c", &op);

        switch(op) {
            case 'I': {
                scanf("%d%d", &pos, &val);
                root = insert(root, pos-1, val);
                break; }
            case 'R': {
                scanf("%d%d", &x, &y);
                root = reverse(root, x-1, y);
                break; }
            case 'A': {
                scanf("%d", &pos);
                printf("%d\n", kth(root, pos-1)->val);
                break; }
            case 'D': {
                scanf("%d%d", &x, &y);
                root = remove(root, x-1, y);
                break; } } }

    dfs(root);
    printf("\n");

    return 0; }