Cod sursa(job #2413523)

Utilizator triscacezarTrisca Vicol Cezar triscacezar Data 23 aprilie 2019 14:47:25
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("secv8.in");
ofstream g("secv8.out");

namespace Treap{
    struct Node{
        Node *l=0,*r=0;
        int x=0;
        int y=0;
        int sz=0;
        int rev=0;
        Node(int _x=0): x(_x), y(rand()), rev(1), sz(1) {}
        void recalc();
    };
    int cnt(Node *t){
        if(!t)return 0;
        return t->sz;
    }
    void Node::recalc(){
        sz=cnt(l)+cnt(r)+1;
        if(rev){
            rev=0;
            swap(l,r);
            if(l) l->rev^=1;
            if(r) r->rev^=1;
        }
    }
    pair<Node*,Node*> split(Node *t,int k){
        if(!t)return {};

        t->recalc();
        if(cnt(t->l)>=k){
            auto pa=split(t->l,k);
            t->l=pa.second;
            t->recalc();
            return {pa.first,t};
        }else{
            auto pa=split(t->r,k-cnt(t->l)-1);
            t->r=pa.first;
            t->recalc();
            return {t,pa.second};
        }

        return {};
    }
    Node* join(Node* l,Node* r)
    {
        if(!l)return r;
        if(!r)return l;

        l->recalc();
        r->recalc();

        if(l->y > r->y)
        {
            l->r=join(l->r,r);
            l->recalc();
            return l;
        }else{
            r->l=join(l,r->l);
            r->recalc();
            return r;
        }
    }
    int acces(Node* t,int k){
        if(!t) return -1;
        t->recalc();
        if(cnt(t->l)+1==k)return t->x;
        if(cnt(t->l)>=k) return acces(t->l,k);
        return acces(t->r,k-cnt(t->l)-1);
    }
    Node* insert(Node* t,int k,int e){
        auto pa=split(t,k-1);
        return join(pa.first,join(new Node(e),pa.second));
    }
    Node* reverse(Node* t,int i,int j){
        auto pa=split(t,i-1);
        auto u =split(pa.second,j-i+1);
        u.first->rev^=1;
		return join(pa.first, join(u.first, u.second));
    }
    Node* erase(Node* t,int i,int j){
        auto pa=split(t,i-1);
        auto u =split(pa.second,j-i+1);
        return join(pa.first,u.second);
    }
    void output(Node* t){
        if(!t)return ;
        t->recalc();
        output(t->l);
        g<<(t->x)<<' ';
        output(t->r);
        return ;
    }
}

int main()
{
    srand(time(nullptr));
    Treap::Node *root=0;
    int n,k,e;char c;
    f>>n>>c;
    for(int i=1;i<=n;i++){
        f>>c;
        if(c=='I'){
            f>>k>>e;
            root=Treap::insert(root,k,e);
        }
        if(c=='A'){
            f>>k;
            g<<Treap::acces(root,k)<<'\n';
        }
        if(c=='R'){
            int a,b;
            f>>a>>b;
            root=Treap::reverse(root,a,b);
        }
        if(c=='D'){
            int a,b;
            f>>a>>b;
            root=Treap::erase(root,a,b);
        }
    }
    Treap::output(root);
    return 0;
}