Cod sursa(job #2642653)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 16 august 2020 16:58:58
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.86 kb
#include <fstream>
#include <random>

using namespace std;

ifstream cin("secv8.in");
ofstream cout("secv8.out");

const int MOD = 1e9 + 7;

struct Treap
{
    int nr;
    int priority;
    int sz;

    bool rev;

    Treap *left, *right;
};

Treap *root, *nil;

void UnRev(Treap* &n)
{
    if(n-> rev == true)
    {
        swap(n-> left, n-> right);
        n-> left-> rev ^= 1;
        n-> right-> rev ^= 1;
        n-> rev = 0;
    }
}

void Recompute(Treap* &n)
{
    n-> sz = n-> left-> sz + n-> right-> sz + 1;
}

Treap* Join(Treap *l, Treap *r)
{
    if(l == nil)
        return r;

    if(r == nil)
        return l;

    UnRev(l);
    UnRev(r);

    if(l-> priority > r-> priority)
    {
        l-> right = Join(l-> right, r);
        Recompute(l);
        return l;
    }

    r-> left = Join(l, r-> left);
    Recompute(r);
    return r;
}

pair < Treap*, Treap* > Split(Treap* root, int lsz)
{
    if(root == nil)
        return {nil, nil};

    UnRev(root);

    if(lsz == 0)
        return {nil, root};

    pair < Treap*, Treap* > ans;

    if(lsz <= root-> left-> sz)
    {
        pair < Treap*, Treap* > aux = Split(root-> left, lsz);
        ans.first = aux.first;
        root-> left = aux.second;
        ans.second = root;
    }
    else
    {
        pair < Treap*, Treap* > aux = Split(root-> right, lsz - root-> left-> sz - 1);
        ans.second = aux.second;
        root-> right = aux.first;
        ans.first = root;
    }

    Recompute(root);
    return ans;
}

Treap* Insert(Treap* &n, int lsz, int val, int priority)
{
    if(n == nil)
    {
        return new Treap
        {
            val,
            priority,
            1,
            false,
            nil,
            nil
        };
    }

    UnRev(n);

    if(priority > n-> priority)
    {
        pair <Treap*, Treap*> ans = Split(n, lsz);
        Treap *nr = new Treap
        {
            val,
            priority,
            1,
            false,
            ans.first,
            ans.second
        };
        Recompute(nr);
        return nr;
    }

    if(lsz <= n-> left-> sz)
    {
        n-> left = Insert(n-> left, lsz, val, priority);
        Recompute(n);
        return n;
    }

    n-> right = Insert(n-> right, lsz - n-> left-> sz - 1, val, priority);
    Recompute(n);
    return n;
}

int kth(Treap* &n, int k)
{
    if(n == nil)
        return -1;

    UnRev(n);

    if(n-> left-> sz + 1 == k)
        return n-> nr;

    if(n-> left-> sz >= k)
        return kth(n-> left, k);

    return kth(n-> right, k - n-> left-> sz - 1);
}

void Reverse(Treap* &n, int x, int y)
{
    pair <Treap*, Treap*> ans = Split(n, x - 1);
    pair <Treap*, Treap*> ans2 = Split(ans.second, y - x + 1);
    ans2.first-> rev ^= 1;
    Treap* r = Join(ans2.first, ans2.second);
    n = Join(ans.first, r);
}

void Delete(Treap* &n, int x, int y)
{
    pair <Treap*, Treap*> ans = Split(n, x - 1);
    pair <Treap*, Treap*> ans2 = Split(ans.second, y - x + 1);
    n = Join(ans.first, ans2.second);
}

void Traverse(Treap *n)
{
    if(n == nil)
        return;

    UnRev(n);

    Traverse(n-> left);
    cout << n-> nr << ' ';
    Traverse(n-> right);
}

int main()
{
    nil = new Treap
    {
        -1,
            -MOD,
            0,
            false,
            NULL,
            NULL
        };

    root = nil;

    int N;
    bool isRev;

    cin >> N >> isRev;

    while(N--)
    {
        char c;
        int x, y;
        cin >> c;

        if(c == 'I')
        {
            cin >> x >> y;
            root = Insert(root, x - 1, y, ((rand() << 15) + rand()) % MOD);
        }
        else if(c == 'A')
        {
            cin >> x;
            cout << kth(root, x) << '\n';
        }
        else if(c == 'R')
        {
            cin >> x >> y;
            Reverse(root, x, y);
        }
        else
        {
            cin >> x >> y;
            Delete(root, x, y);
        }
    }

    Traverse(root);

    return 0;
}