Cod sursa(job #2507305)

Utilizator vladvlad00Vlad Teodorescu vladvlad00 Data 9 decembrie 2019 22:21:33
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <random>
#include <fstream>

using namespace std;

ifstream fin("secv8.in");
ofstream fout("secv8.out");

mt19937 rnd((long long)(new char));

typedef struct treap * arb;

arb gol;

struct treap {
    int rev;
    int val;
    int size;
    long long prio;
    arb st, dr;

    void propaga()
    {
        if (!rev)
            return;
        swap(st, dr);
        st->rev ^= 1;
        dr->rev ^= 1;
        rev = 0;
    }

    void updSize()
    {
        size = 1 + st->size + dr->size;
    }

    pair<arb,arb> split(int poz)
    {
        if (this == gol)
            return {gol, gol};
        propaga();
        if (st->size < poz)
        {
            auto rez = dr->split(poz - st->size - 1);
            dr = rez.first;
            updSize();
            return {this, rez.second};
        }
        else
        {
            auto rez = st->split(poz);
            st = rez.second;
            updSize();
            return {rez.first, this};
        }
    }

    arb ins(int poz, int val);
    arb del(int l, int r);
    arb reverse(int l, int r);
    int access(int poz);
    void inordine()
    {
        if (this == gol)
            return;
        propaga();
        st->inordine();
        fout << val << ' ';
        dr->inordine();
    }

    treap(int v = 0) : rev(0), val(v), size(1), prio(rnd()), st(gol),  dr(gol) { }
};

arb join(arb x, arb y)
{
    if (x == gol)
        return y;
    if (y == gol)
        return x;
    if (x->prio < y->prio) {
        y->propaga();
        arb rez = join(x, y->st);
        y->st = rez;
        y->updSize();
        return y;
    }
    else
    {
        x->propaga();
        arb rez = join(x->dr, y);
        x->dr = rez;
        x->updSize();
        return x;
    }
}

arb treap::ins(int poz, int v)
{
    propaga();
    auto rez = split(poz - 1);
    arb nod = new treap(v);
    rez.first = join(rez.first, nod);
    return join(rez.first, rez.second);
}

arb treap::del(int l, int r)
{
    propaga();
    auto rez = split(r);
    auto aux = rez.first->split(l - 1);
    return join(aux.first, rez.second);
}

arb treap::reverse(int l, int r)
{
    propaga();
    auto rez = split(r);
    auto aux = rez.first->split(l - 1);
    aux.second->rev ^= 1;
    aux.second->propaga();
    rez.first = join(aux.first, aux.second);
    return join(rez.first, rez.second);
}

int treap::access(int poz)
{
    propaga();
    if (poz == st->size + 1)
        return val;
    if (poz <= st->size)
        return st->access(poz);
    return dr->access(poz - st->size - 1);
}

int main()
{
    int n, x, y, PLSWORK;
    char op;

    gol = new treap;
    gol->size = 0;
    gol->st = gol->dr = gol;
    gol->prio = 0;

    arb t = gol;

    fin >> n >> PLSWORK;
    while (n--)
    {
        fin >> op;
        switch(op)
        {
            case 'I':
                fin >> x >> y;
                t = t->ins(x,y);
                break;
            case 'A':
                fin >> x;
                fout << t->access(x) << '\n';
                break;
            case 'R':
                fin >> x >> y;
                t = t->reverse(x,y);
                break;
            case 'D':
                fin >> x >> y;
                t = t->del(x,y);
                break;
        }
    }
    t->inordine();
    return 0;
}