Cod sursa(job #1423260)

Utilizator Kira96Denis Mita Kira96 Data 21 aprilie 2015 17:13:08
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include<fstream>
#include<cstdlib>
#define FOR(a,b,c) for(register int a=b;a<=c;++a)
#include<ctime>
using namespace std;
ifstream f("secv8.in");
ofstream g("secv8.out");
int m,x,lef,rig,po;
char tip;
struct Tr
{
    Tr *l,*r;
    int key,pr,cnt,val,rev;
    Tr() {}
    Tr(int _key,int _pr,int _val)
    {
        rev=0;
        key=_key;
        cnt=1;
        l=r=NULL;
        pr=_pr;
        val=_val;
    }
};
#define T Tr*
T R=NULL;
int cnt(T t)
{
    if(!t)
        return 0;
    return t->cnt;
}
void upd(T &t)
{
    if(t)
        t->cnt=cnt(t->l)+cnt(t->r)+1;
}
void push(T &t)
{
    if(t&&t->rev)
    {
        t->rev=0;
        swap(t->l,t->r);
        if(t->l) t->l->rev^=1;
        if(t->r) t->r->rev^=1;
    }
}
void split(T t,T &l,T &r,int key,int add)
{
    if(!t)
        return void(l=r=NULL);
    push(t);
    int cur_key=add+cnt(t->l)+1;
    if(key<=cur_key)
        split(t->l,l,t->l,key,add),r=t;
    else
        split(t->r,t->r,r,key,cur_key),l=t;
    upd(t);
}
void merge(T &t,T l,T r)
{
    push(l);
    push(r);
    if(!l||!r)
        t=l?l:r;
    else
    if(l->pr > r->pr)
        merge(l->r,l->r,r),t=l;
    else
        merge(r->l,l,r->l),t=r;
    upd(t);
}
void insert(T &t,T it,int add)
{
    push(t);
    if(!t)
        t=it;
    else
    if(it->pr > t->pr)
        split(t,it->l,it->r,it->key,add), t=it;
    else
    if(it->key>add+cnt(t->l)+1)
        insert(t->r,it,add+cnt(t->l)+1);
    else
        insert(t->l,it,add);
    upd(t);
}
void erase(T &t,int key,int add)
{
    push(t);
    int cur_key=cnt(t->l)+add+1;
    if(cur_key==key)
        merge(t,t->l,t->r);
    else
    if(key<cur_key)
        erase(t->l,key,add);
    else
        erase(t->r,key,cur_key);
    upd(t);
}
int query(T t,int key,int add)
{
    push(t);
    int cur_key=add+cnt(t->l)+1;
    if(key==cur_key)
        return t->val;
    if(key<cur_key)
        return query(t->l,key,add);
    else
        return query(t->r,key,cur_key);
}
void reverse(int lef,int rig)
{
    Tr *it1,*it2,*it3;
    it1=it2=it3=NULL;
    split(R,it1,it2,lef,0);
    split(it2,it2,it3,rig-lef+2,0);
    it2->rev^=1;
    merge(R,it1,it2);
    merge(R,R,it3);
}
void dfs(T t)
{
    if(!t)
        return;
    push(t);
    dfs(t->l);
    g<<t->val<<" ";
    dfs(t->r);
}
int main()
{
    srand(time(0));
    f>>m>>tip;
    while(m--)
    {
        f>>tip;
        if(tip=='I')
        {
            f>>po>>x;
            T it=new Tr(po,rand()+1,x);
            insert(R,it,0);
        }
        else
        if(tip=='A')
        {
            f>>po;
            g<<query(R,po,0)<<"\n";
        }
        else
        if(tip=='R')
        {
            f>>lef>>rig;
            reverse(lef,rig);
        }
        else
        {
            f>>lef>>rig;
            FOR(j,lef,rig)
                erase(R,lef,0);
        }
    }
    dfs(R);
    return 0;
}
//Look at me! Look at me! The monster inside me has grown this big!