Cod sursa(job #2211812)

Utilizator JuniorChallenge2018Junior Challenge JuniorChallenge2018 Data 11 iunie 2018 21:53:40
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.5 kb
/**
Bogdan Sitaru
Treap
**/
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

namespace Treap
{
    mt19937 gen;
    uniform_int_distribution<int> uid;

    struct Node
    {
        int val = 0, pr = 0, sz = 0, rev = 0;
        Node* l = 0, * r = 0, * f = 0;

        Node() { ; }
        Node(int _val, int _pr, Node* _l, Node* _r, Node* _f)
        {
            val = _val, pr = _pr, sz = 1, rev = 0;
            l = _l, r = _r, f = _f;
        }
    };
    Node* nil, * R;

    int newPriority()
    {
        return uid(gen);
    }

    void init()
    {
        gen = mt19937(chrono::high_resolution_clock::now().time_since_epoch().count());
        uid = uniform_int_distribution<int>(1, 2e9);

        nil = new Node();
        nil -> l = nil -> r = nil -> f = nil;

        R = nil;
    }

    void remake(Node* T)
    {
        if(T == nil)    return;
        T -> sz = T -> l -> sz + 1 + T -> r -> sz;
        if(T -> l != nil)   T -> l -> f = T;
        if(T -> r != nil)   T -> r -> f = T;
    }

    void lazy(Node* T)
    {
        if(T == nil)    return;
        if(!T -> rev)   return;
        T -> rev = 0;
        swap(T -> l, T -> r);
        if(T -> l != nil)   T -> l -> rev ^= 1;
        if(T -> r != nil)   T -> r -> rev ^= 1;
    }

    Node* join(Node* l, Node* r)
    {
        if(l == nil)    return r;
        if(r == nil)    return l;

        lazy(l); lazy(r);

        if(l -> pr > r -> pr)
        {
            l -> r = join(l -> r, r);
            remake(l);
            return l;
        }
        else
        {
            r -> l = join(l, r -> l);
            remake(r);
            return r;
        }
        return nil;
    }

    pair<Node*, Node*> split(Node* T, int pos)
    {
        if(T == nil) return {nil, nil};

        lazy(T);

        if(T -> l -> sz >= pos)
        {
            auto aux = split(T -> l, pos);
            T -> l = aux.second;
            remake(T);
            aux.second = T;
            aux.first -> f = nil;
            return aux;
        }
        else
        {
            auto aux = split(T -> r, pos - T -> l -> sz - 1);
            T -> r = aux.first;
            remake(T);
            aux.first = T;
            aux.second -> f = nil;
            return aux;
        }

        return {nil, nil};
    }

    void insert(int val, int pos)
    {
        Node* nd = new Node(val, newPriority(), nil, nil, nil);
        auto l_r = split(R, pos);
        auto lm = join(l_r.first, nd);
        R = join(lm, l_r.second);
    }

    void reverse(int st, int dr)
    {
        auto lm_r = split(R, dr);
        auto l_m = split(lm_r.first, st - 1);
        l_m.second -> rev ^= 1;
        auto lm = join(l_m.first, l_m.second);
        R = join(lm, lm_r.second);
    }

    void erase(int st, int dr)
    {
        auto lm_r = split(R, dr);
        auto l_m = split(lm_r.first, st - 1);
        R = join(l_m.first, lm_r.second);
    }

    int access(int pos)
    {
        auto lm_r = split(R, pos);
        auto l_m = split(lm_r.first, pos - 1);
        int val = l_m.second -> val;
        auto lm = join(l_m.first, l_m.second);
        R = join(lm, lm_r.second);
        return val;
    }

    void print(Node* T)
    {
        if(T == nil)    return;
        lazy(T);
        print(T -> l);
        printf("%d ", T -> val);
        print(T -> r);
    }

    void print() { print(R); printf("\n"); }
}

int main()
{
    #ifdef FILE_IO
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    #endif

    Treap::init();

    int Q, u;
    scanf("%d%d", &Q, &u);

    for(int q = 1; q <= Q; q++)
    {
        //Treap::print();

        char ch = getchar();
        while(ch != 'I' && ch != 'R' && ch != 'D' && ch != 'A') ch = getchar();

        if(ch == 'I')
        {
            int x, p;
            scanf("%d%d", &p, &x);
            Treap::insert(x, p - 1);
        }
        else if(ch == 'R')
        {
            int st, dr;
            scanf("%d%d", &st, &dr);
            Treap::reverse(st, dr);
        }
        else if(ch == 'D')
        {
            int st, dr;
            scanf("%d%d", &st, &dr);
            Treap::erase(st, dr);
        }
        else if(ch == 'A')
        {
            int pos;
            scanf("%d", &pos);
            int ans = Treap::access(pos);
            printf("%d\n", ans);
        }
    }

    Treap::print();

    return 0;
}