Cod sursa(job #2335865)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 4 februarie 2019 16:23:01
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.88 kb
#include <bits/stdc++.h>

#define ll long long

using namespace std;

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

ll rand15 ()
{
    return rand() % (1LL << 15LL);
}

ll rand30 ()
{
    return rand15() ^ (rand15() << 15LL);
}

ll rand60 ()
{
    return rand30() ^ (rand30() << 30LL);
}

struct Treap
{
    int size;
    int value;
    ll priority;
    bool isReversed;
    Treap* left;
    Treap* right;
};

Treap* emptyTreap = new Treap {0, 0, 0, false, emptyTreap, emptyTreap};
Treap* Root = emptyTreap;

Treap* Tuntangle(Treap* root);

void Tdump (Treap* root, bool reversed = false, int depth = 0)
{
    if (root != emptyTreap) {
        if (reversed ^ root->isReversed) {
            Tdump(root->left, true, depth + 1);
            for(int i = 1; i <= depth; i++)
                cout << "  ";
            cout << root->value << " " << root->isReversed << " " << root->size << "\n";
            Tdump(root->right, true, depth + 1);
        } else {
            Tdump(root->right, false, depth + 1);
            for(int i = 1; i <= depth; i++)
                cout << "  ";
            cout << root->value << " " << root->isReversed << " " << root->size << "\n";
            Tdump(root->left, false, depth + 1);
        }
    }
}

Treap* Tcompute (Treap* root, Treap* left, Treap* right)
{
    root->size = left->size + right->size + 1;
    root->left = left;
    root->right = right;
    return root;
}

Treap* Tuntangle (Treap* root)
{
    if(root->isReversed)
    {
        root->isReversed = false;
        if(root->left != emptyTreap)
            root->left->isReversed = !root->left->isReversed;
        if(root->right != emptyTreap)
            root->right->isReversed = !root->right->isReversed;
        swap(root->left, root->right);
    }
    return root;
}

Treap* Tjoin (Treap* first, Treap* second)
{
    first = Tuntangle(first);
    second = Tuntangle(second);
    if(first == emptyTreap)
        return second;
    else if(second == emptyTreap)
        return first;
    else if(first->priority > second->priority)
        return Tcompute(first, first->left, Tjoin(first->right, second));
    else
        return Tcompute(second, Tjoin(first, second->left), second->right);
}

pair <Treap*, Treap*> TsplitSize (Treap* root, int firstSize)
{
    root = Tuntangle(root);
    pair <Treap*, Treap*> answer;
    if(root == emptyTreap)
    {
        answer.first = emptyTreap;
        answer.second = emptyTreap;
    }
    else if(firstSize <= root->left->size)
    {
        auto p = TsplitSize(root->left, firstSize);
        answer.first = p.first;
        answer.second = Tcompute(root, p.second, root->right);
    }
    else
    {
        auto p = TsplitSize(root->right, firstSize - root->left->size - 1);
        answer.first = Tcompute(root, root->left, p.first);
        answer.second = p.second;
    }
    return answer;
}

Treap* Treverse (Treap* root, int left, int right)
{
    auto p = TsplitSize(root, right);
    auto p1 = TsplitSize(p.first, left - 1);
    p1.second->isReversed = !p1.second->isReversed;
    return Tjoin(Tjoin(p1.first, p1.second), p.second);
}

Treap* Tinsert (Treap* root, int pos, int value)
{
    auto p = TsplitSize(root, pos - 1);
    Treap* newTreap = new Treap {1, value, rand60(), false, emptyTreap, emptyTreap};
    return Tjoin(Tjoin(p.first, newTreap), p.second);
}

Treap* Tdelete (Treap* root, int left, int right)
{
    auto p = TsplitSize(root, right);
    auto p1 = TsplitSize(p.first, left - 1);
    return Tjoin(p1.first, p.second);
}

int Taccess (Treap* root, int pos)
{
    Tuntangle(root);
    if (root == emptyTreap)
        return -1;
    else if (pos <= root->left->size)
        return Taccess(root->left, pos);
    else if (root->left->size + 1 == pos)
        return root->value;
    else
        return Taccess(root->right, pos - root->left->size - 1);
}

void Tprint (Treap* root)
{
    if (root != emptyTreap)
    {
        Tuntangle(root);
        Tprint(root->left);
        fout << root->value << " ";
        Tprint(root->right);
    }
}

int q;
bool rev;

int main()
{
    fin >> q >> rev;
    while(q--)
    {
        char op;
        fin >> op;
        if(op == 'I')
        {
            int pos, value;
            fin >> pos >> value;
            Root = Tinsert(Root, pos, value);
        }
        else if(op == 'A')
        {
            int pos;
            fin >> pos;
            fout << Taccess(Root, pos) << "\n";
        }
        else if(op == 'R')
        {
            int left, right;
            fin >> left >> right;
            Root = Treverse(Root, left, right);
        }
        else if(op == 'D')
        {
            int left, right;
            fin >> left >> right;
            Root = Tdelete(Root, left, right);
        }
    }
    Tprint(Root);
    return 0;
}