Cod sursa(job #1303118)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 27 decembrie 2014 17:15:56
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.88 kb
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

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

int get_rand()
{
    return rand()%(1<<15)*(1<<15) + rand()%(1<<15);
}

struct node
{
    int x,prio,sub;
    int sw;
    node *l,*r;

    node (int val, int pr)
    {
        x = val;
        prio = pr;
        sub = 1;
        sw = 0;
        l = NULL;
        r = NULL;
    }

    int key ()
    {
        if (l == NULL)
          return 0;
        return l->sub;
    }

    void update ()
    {
        sub = 1;

        if (l != NULL)
          sub += l->sub;
        if (r != NULL)
          sub += r->sub;
    }

    void lazy ()
    {
        if (sw)
        {
           swap (l,r);
           if (l != NULL)
             l->sw ^= 1;
           if (r != NULL)
             r->sw ^= 1;
           sw = 0;
        }
    }
}*T;

void split (node *T, node *&L, node*&R, int key, int add)
{
    if (T == NULL)
    {
        L = R = NULL;
        return;
    }

    T->lazy();

    if (T->key() + add < key)
    {
        L = T;
        split (T->r,L->r,R,key,add+T->key()+1);
        L->update();
    }
    else
    {
        R = T;
        split (T->l,L,R->l,key,add);
        R->update();
    }
}

void merge (node *&T, node *L, node *R)
{
    if (L == NULL)
    {
        T = R;
        return;
    }
    if (R == NULL)
    {
        T = L;
        return;
    }

    if (L->prio < R->prio)
    {
        L->lazy();
        T = L;
        merge (T->r,L->r,R);
        T->update();
    }
    else
    {
        R->lazy();
        T = R;
        merge (T->l,L,R->l);
        T->update();
    }
}

void insert (node *&T, int x, int prio, int key, int add)
{
    if (T == NULL)
    {
        T = new node (x,prio);
        return;
    }

    T->lazy();

    if (T->prio > prio)
    {
        node *L,*R;
        split (T,L,R,key,add);
        T = new node (x,prio);
        T->l = L;
        T->r = R;
    }
    else if (T->key() + add < key)
    {
        insert (T->r,x,prio,key,add+T->key()+1);
    }
    else insert (T->l,x,prio,key,add);

    T->update();
}

void erase (node *&T, int key, int add)
{
    T->lazy();

    if (T->key() + add == key)
    {
        node *L = T->l, *R = T->r;
        delete T;
        merge (T,L,R);
    }
    else if (T->key() + add < key)
    {
        erase (T->r,key,add+T->key()+1);
    }
    else erase (T->l,key,add);

    if (T != NULL)
      T->update();
}

int find (node *&T, int key, int add)
{
    T->lazy();

    if (T->key() + add == key)
    {
        return T->x;
    }
    else if (T->key() + add < key)
    {
        return find (T->r,key,add+T->key()+1);
    }
    else return find (T->l,key,add);
}

void reverse (node *&T, int key1, int key2)
{
    node *T1,*T2,*T3;

    split (T,T1,T2,key1,0);
    split (T2,T2,T3,key2+1,0);

    T2->sw ^= 1;
    T2->lazy();

    merge (T,T1,T2);
    merge (T,T,T3);
}

void dfs (node *T)
{
    if (T == NULL)
      return;
    T->lazy();

    dfs (T->l);
    fout<<T->x<<" ";
    dfs (T->r);
}

int main()
{
    int n,x,y;
    char op;

    srand (time(NULL));

    fin>>n>>x;

    for (int i=1; i<=n; ++i)
    {
        fin>>op;

        if (op == 'I')
        {
            fin>>x>>y;
            --x;
            insert (T,y,get_rand(),x,0);
        }
        else if (op == 'A')
        {
            fin>>x;
            --x;
            fout<<find (T,x,0)<<"\n";
        }
        else if (op == 'R')
        {
            fin>>x>>y;
            --x;
            --y;

            reverse (T,x,y);
        }
        else
        {
            fin>>x>>y;
            --x;
            --y;

            for (int i=x; i<=y; ++i)
              erase (T,x,0);
        }
    }

    dfs (T);
}