Cod sursa(job #3350573)

Utilizator unomMirel Costel unom Data 9 aprilie 2026 19:12:12
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.84 kb
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct Node
{
    int val;
    int lazy;
    int sz;
    int prio;
    Node *left;
    Node *right;

    Node (int x)
    {
        val = x;
        lazy = 0;
        sz = 1;
        prio = rng();
        left = nullptr;
        right = nullptr;
    }

    void recalc()
    {
        sz = 1;
        if(left != nullptr) sz += left->sz;
        if(right != nullptr) sz += right->sz;
    }

    void apply_lazy(int val)
    {
        if(val == 1)
        {
            lazy ^= 1;
            swap(left, right);
        }
    }

    void push_lazy()
    {
        if(lazy == 1)
        {
            if(left != nullptr) left->apply_lazy(lazy);
            if(right != nullptr) right->apply_lazy(lazy);

            lazy = 0;
        }
    }
};

ifstream in("secv8.in");
ofstream out("secv8.out");
int q, r;

pair<Node*, Node*> split(Node *treap, int x)
{
    if(treap == nullptr)
    {
        return {nullptr, nullptr};
    }
    treap->push_lazy();

    int ind = 1;
    if(treap->left != nullptr) ind += treap->left->sz;

    if(ind <= x)
    {
        auto [left, right] = split(treap->right, x - ind);
        treap->right = left;
        treap->recalc();

        return {treap, right};
    }
    else
    {
        auto [left, right] = split(treap->left, x);
        treap->left = right;
        treap->recalc();

        return {left, treap};
    }
}

Node *merge(Node *left, Node *right)
{
    if(left == nullptr) return right;
    if(right == nullptr) return left;

    left->push_lazy();
    right->push_lazy();

    if(left->prio > right->prio)
    {
        left->right = merge(left->right, right);
        left->recalc();

        return left;
    }
    else
    {
        right->left = merge(left, right->left);
        right->recalc();

        return right;
    }
}

Node *add(Node *treap, int poz, int val)
{
    auto [left, right] = split(treap, poz - 1);
    Node *newNode = new Node(val);

    return merge(left, merge(newNode, right));
}

Node *reverse(Node *treap, int st, int dr)
{
    auto [left, full_right] = split(treap, st - 1);
    auto [sub, right] = split(full_right, dr - st + 1);

    sub->apply_lazy(1);

    return merge(left, merge(sub, right));
}

void clear(Node *treap)
{
    if(treap == nullptr) return;

    clear(treap->left);
    clear(treap->right);

    delete treap;
}

Node *del(Node *treap, int st, int dr)
{
    auto [left, full_right] = split(treap, st - 1);
    auto [sub, right] = split(full_right, dr - st + 1);

    clear(sub);

    return merge(left, right);
}

int query(Node *treap, int poz)
{
    treap->push_lazy();

    int left_sz = (treap->left != nullptr) ? treap->left->sz : 0;
    if(poz <= left_sz)
    {
        return query(treap->left, poz);
    }
    else if(poz == left_sz + 1)
    {
        return treap->val;
    }
    else
    {
        return query(treap->right, poz - left_sz - 1);
    }
}

void show(Node *treap)
{
    if(treap == nullptr) return;
    treap->push_lazy();

    show(treap->left);
    out<<treap->val<<" ";
    show(treap->right);
}

int main()
{
    Node *treap = nullptr;

    in>>q>>r;

    char tip;
    int x, y;
    while(q--)
    {
        in>>tip;

        if(tip == 'I')
        {
            in>>x>>y;
            treap = add(treap, x, y);
        }
        else if(tip == 'A')
        {
            in>>x;

            out<<query(treap, x)<<'\n';
        }
        else if(tip == 'R')
        {
            in>>x>>y;
            treap = reverse(treap, x, y);
        }
        else
        {
            in>>x>>y;
            treap = del(treap, x, y);
        }
    }

    show(treap);

    return 0;
}