Cod sursa(job #1155243)

Utilizator SRaduRadu Szasz SRadu Data 26 martie 2014 19:37:35
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.43 kb
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct Treap {
    int Key, Priority, Size;
    bool shallReverse;
    Treap *Left, *Right;

    Treap() {}
    Treap(int K, int P, int S, Treap* L, Treap* R) {
        this->Key = K;
        this->Priority = P;
        this->Size = S;
        this->Left = L;
        this->Right = R;
        this->shallReverse = false;
    }
}*T, *nil;

void Init(Treap* &T);
void Insert(Treap* &T, int Key, int Priority, int Position);
void Erase(Treap* &T, int Position);
void DeleteSubsir(Treap* &T, int Left, int Right);
void Split(Treap* &src, Treap* &A, Treap* &B, int Position);
void Join(Treap* &dest, Treap *A, Treap *B);
void Update(Treap* &T);
void RotTrigo(Treap* &T);
void RotAntiTrigo(Treap* &T);
void Balance(Treap* &T);
void GoReverse(Treap* &T);
void Reverse(Treap* &T, int Left, int Right);
int GetElement(Treap* &T, int Position);

const int INF = 0x3f3f3f3f;

int N, K, E, X, Y, WhyShouldICare;
char Op;

void Init(Treap* &T) {
    srand(time(NULL));
    T = nil = new Treap(0, 0, 0, NULL, NULL);
    nil->Left = nil->Right = nil;
}

void Insert(Treap* &T, int Key, int Priority, int Position) {
    if(T == nil) {
        T = new Treap(Key, Priority, 1, nil, nil);
        return;
    }
    
    GoReverse(T);

    if(Position <= T->Left->Size + 1) 
        Insert(T->Left, Key, Priority, Position);
    else 
        Insert(T->Right, Key, Priority, Position - T->Left->Size - 1);

    Update(T);
    Balance(T);
    Update(T);
}

void Erase(Treap* &T, int Position) {
    GoReverse(T);

    if(Position == T->Left->Size + 1) {
        if(T->Left == nil && T->Right == nil) {
            delete T;
            T = nil;
            return;
        }
        if(T->Left->Priority > T->Right->Priority) {
            RotAntiTrigo(T);
            Erase(T->Right, Position - T->Left->Size - 1);
        } else {
            RotTrigo(T);
            Erase(T->Left, Position);
        }
    } else if(Position <= T->Left->Size) {
        Erase(T->Left, Position);
    } else 
        Erase(T->Right, Position - T->Left->Size - 1);
    
    Update(T);
}

void DeleteSubsir(Treap* &T, int L, int R) {
    Treap  *A, *B, *C, *D;
    Split(T, A, B, R + 1);
    Split(A, C, D, L);
    Join(T, C, B);    
}

void Split(Treap* &src, Treap* &A, Treap* &B, int Position) {
    Insert(src, 0, INF, Position);
    A = src->Left, B = src->Right;
    delete src;
    src = nil;
}

void Join(Treap* &dest, Treap *A, Treap *B) {
    dest = new Treap(0, INF, 1, A, B);
    Update(dest);
    Erase(dest, dest->Left->Size + 1);
}

void Update(Treap* &T) {
    T->Size = T->Left->Size + T->Right->Size + 1;
}

void RotTrigo(Treap* &T) {
    GoReverse(T);
    GoReverse(T->Left);
    GoReverse(T->Right);

    Treap *Aux = T->Right;
    T->Right = Aux->Left;
    Aux->Left = T;
    T = Aux;

    Update(T->Left);
    Update(T);
}

void RotAntiTrigo(Treap* &T) {
    GoReverse(T);
    GoReverse(T->Left);
    GoReverse(T->Right);

    Treap *Aux = T->Left;
    T->Left = Aux->Right;
    Aux->Right = T;
    T = Aux;

    Update(T->Right);
    Update(T);
}

void Balance(Treap* &T) {
    if(T->Left->Priority > T->Priority) {
        RotAntiTrigo(T);
    } else if(T->Right->Priority > T->Priority)
        RotTrigo(T);
}

void GoReverse(Treap* &T) {
    if(T->shallReverse) {
        swap(T->Left, T->Right);
        T->Left->shallReverse = T->Right->shallReverse = true;
        T->shallReverse = false;
    }
}

void Reverse(Treap* &T, int Left, int Right) {
    Treap *A, *B, *C, *D;
   
    Split(T, A, B, Right + 1);
    Split(A, C, D, Left);
    
    D->shallReverse = true;
    
    Join(A, C, D);
    Join(T, A, B);
}

int GetElement(Treap* &T, int Position) {
    GoReverse(T);

    if(Position == T->Left->Size + 1)
        return T->Key;
    if(Position <= T->Left->Size)
        return GetElement(T->Left, Position);
    return GetElement(T->Right, Position - T->Left->Size - 1);
}

int main() {
    ifstream in("secv8.in"); ofstream out("secv8.out");
    Init(T);
    for(in >> N >> WhyShouldICare, in.get(); N; N--) {
        in >> Op;
        switch(Op) {
        case 'I': 
            in >> K >> E;
            Insert(T, E, rand() % INF + 1, K);
            break;
        case 'A':
            out << GetElement(T, K) << "\n";
            break;
        case 'R':
            in >> X >> Y;
            Reverse(T, X, Y);
            break;
        case 'D':
            in >> X >> Y;
            DeleteSubsir(T, X, Y);
            break;
        } in.get();
    }
}