Cod sursa(job #3231544)

Utilizator ionicaFulgerulIonica Fulgerul ionicaFulgerul Data 27 mai 2024 03:41:18
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.8 kb
#include <cassert>
#include <fstream>
#include <tuple>

using namespace std;

ifstream f("secv8.in");
ofstream g("secv8.out");

struct nod {
    nod *tt, *fii[2];
    int size, value;
    bool flip;
} *nil = new nod{nullptr, nullptr, nullptr, 0, 0, 0};

static void apply_flip(nod *x) {
    if (x != nil) {
        swap(x->fii[0], x->fii[1]);
        x->flip = !x->flip;
    }
}

static void prop(nod *x) {
    if (x != nil && x->flip) {
        apply_flip(x->fii[0]);
        apply_flip(x->fii[1]);
        x->flip = false;
    }
}

static void mod_fiu(nod *tt, int which, nod *fiu) {
    if (tt != nil && which != -1) {
        tt->fii[which] = fiu;
        tt->size = 1 + tt->fii[0]->size + tt->fii[1]->size;
    }
    if (fiu != nil) fiu->tt = tt;
}

static int which_side(nod *x) {
    return x->tt == nil         ? -1
           : x->tt->fii[0] == x ? 0
           : x->tt->fii[1] == x ? 1
                                : -1;
}

static void rotate(nod *x) {
    nod *y = x->tt, *z = x->tt->tt;
    int sx = which_side(x), sy = which_side(y);
    nod *son = x->fii[sx ^ 1];

    mod_fiu(y, sx, son);
    mod_fiu(x, sx ^ 1, y);
    mod_fiu(z, sy, x);
}

static void splay(nod *x) {
    if (x->tt == nil)
        ;
    else if (x->tt->tt == nil)
        rotate(x);
    else if (which_side(x) == which_side(x->tt)) {
        rotate(x->tt);
        rotate(x);
        splay(x);
    } else {
        rotate(x);
        rotate(x);
        splay(x);
    }
}

static nod *access(nod *x, int nr) {
    assert(nr < x->size);
    while (prop(x), nr != x->fii[0]->size) {
        assert(x != nil);
        if (nr < x->fii[0]->size)
            x = x->fii[0];
        else
            nr -= x->fii[0]->size + 1, x = x->fii[1];
    }
    splay(x);
    return x;
}

static nod *join(nod *x, nod *y) {
    if (x == nil) return y;
    if (y == nil) return x;
    y = access(y, 0);
    mod_fiu(y, 0, x);
    return y;
}

static pair<nod *, nod *> split(nod *x, int nr) {
    if (nr == 0) return make_pair(nil, x);
    if (x->size == nr) return make_pair(x, nil);
    x = access(x, nr);
    nod *y = x->fii[0];
    mod_fiu(x, 0, nil);
    mod_fiu(nil, 0, y);
    return make_pair(y, x);
}

static nod *insert_at_pos(nod *x, int poz, int value) {
    auto [st, dr] = split(x, poz);
    return join(join(st, new nod{nil, nil, nil, 1, value, false}), dr);
}

static tuple<nod *, nod *, nod *> split3(nod *x, int st, int dr) {
    auto [tmp, n_dr] = split(x, dr);
    auto [n_st, n_mid] = split(tmp, st);
    return make_tuple(n_st, n_mid, n_dr);
}

static nod *flip(nod *x, int st, int dr) {
    auto [n_st, n_mid, n_dr] = split3(x, st, dr);
    apply_flip(n_mid);
    return join(join(n_st, n_mid), n_dr);
}

static void del_tree(nod *x) {
    if (x != nil) {
        del_tree(x->fii[0]);
        del_tree(x->fii[1]);
        delete x;
    }
}

static nod *del(nod *x, int st, int dr) {
    auto [n_st, n_mid, n_dr] = split3(x, st, dr);
    del_tree(n_mid);
    return join(n_st, n_dr);
}

static void print_tree(nod *x) {
    if (x == nil) return;
    prop(x);
    print_tree(x->fii[0]);
    cout << x->value << ' ';
    print_tree(x->fii[1]);
}

int main() {
    int q, t;
    f >> q >> t;

    nod *root = nil;

    while (q--) {
        char ch;
        f >> ch;
        int k, e, i, j;
        switch (ch) {
            case 'I':
                f >> k >> e;
                root = insert_at_pos(root, k - 1, e);
                break;
            case 'A':
                f >> k;
                root = access(root, k - 1);
                g << root->value << '\n';
                break;
            case 'R':
                f >> i >> j;
                --i;
                root = flip(root, i, j);
                break;
            case 'D':
                f >> i >> j;
                --i;
                root = del(root, i, j);
                break;
        }
    }
    print_tree(root);
}