Cod sursa(job #2009875)

Utilizator silkMarin Dragos silk Data 11 august 2017 01:20:03
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.85 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <ctime>
using namespace std;

vector<int> v;

struct Treap{
    int key, priority, rev, cnt;
    Treap *left, *right;
    Treap() {}
    Treap(int key, int priority, Treap *left, Treap *right){
        this->cnt = 1;
        this->rev = 0;
        this->key = key;
        this->priority = priority;
        this->left = left; this->right = right;
    }
};

Treap *R = NULL;

void Update(Treap* &T)
{
    if(!T) return;
    if(T->left) T->left->rev ^= T->rev;
    if(T->right) T->right->rev ^= T->rev;
    if(T->rev){
        Treap *S = T->left; T->left = T->right; T->right = S;
        T->rev = 0;
    }
}

void GetCnt(Treap* &T)
{
    T->cnt = (T->left ? T->left->cnt : 0) + (T->right ? T->right->cnt : 0) + 1;
}

void RotLeft(Treap* &T)
{
    Treap* S = T->left;
    T->left = S->right;
    S->right = T;
    T = S;
    GetCnt(T); GetCnt(T->right);
}

void RotRight(Treap* &T)
{
    Treap* S = T->right;
    T->right = S->left;
    S->left = T;
    T = S;
    GetCnt(T); GetCnt(T->left);
}

void Balance(Treap* &T)
{
    if(T->left && T->left->priority < T->priority) RotLeft(T);
    else if(T->right && T->right->priority < T->priority) RotRight(T);
    GetCnt(T);
}

void Insert(Treap* &T, int k, int key, int priority)
{
    if(!T){
        T = new Treap(key, priority, 0, 0);
        return;
    }

    Update(T); Update(T->left); Update(T->right);
    if((T->left ? T->left->cnt : 0) >= k) Insert(T->left, k, key, priority);
    else Insert(T->right, k - (T->left ? T->left->cnt : 0) - 1, key, priority);
    Balance(T);
}

int Search(Treap* &T, int k)
{
    Update(T); Update(T->left); Update(T->right);
    if((T->left ? T->left->cnt : 0) + 1 == k) return T->key;
    if((T->left ? T->left->cnt : 0) >= k) return Search(T->left, k);
    return Search(T->right, k - (T->left ? T->left->cnt : 0) - 1);
}

void Erase(Treap* &T)
{
    if(!T->left && !T->right){
        delete T, T = 0;
        return;
    }

    Update(T); Update(T->left); Update(T->right);
    if(T->left && T->right)
        (T->left->priority < T->right->priority) ? (RotLeft(T), Erase(T->right)) : (RotRight(T), Erase(T->left));
    else if(T->left) RotLeft(T), Erase(T->right);
    else RotRight(T), Erase(T->left);

    GetCnt(T);
}

void Reverse(int i, int j)
{
    Treap *Ts, *Td, *T;

    Insert(R, i-1, 0, 0);
    Insert(R->right, j-i+1, 0, 0);
    Ts = R->left; T = R->right->left; Td = R->right->right;

    delete R->right; delete R;

    T->rev ^= 1;
    R = new Treap(0, 0, Ts, T);
    Erase(R);

    T = R; R = new Treap(0, 0, T, Td);
    Erase(R);
}

void Delete(int i, int j)
{
    Treap *Ts, *Td;

    Insert(R, i-1, 0, 0);
    Insert(R->right, j-i+1, 0, 0);
    Ts = R->left; Td = R->right->right;

    delete R->right; delete R;

    R = new Treap(0, 0, Ts, Td);
    Erase(R);
}

void Inorder(Treap* T)
{
    Update(T); Update(T->left); Update(T->right);
    if(T->left) Inorder(T->left);
    v.push_back(T->key);
    if(T->right) Inorder(T->right);
}

int main(){
    FILE* fin = fopen("secv8.in","r");
    FILE* fout = fopen("secv8.out","w");

    int i,M,x,k,y,z;
    char Q;

    srand(time(NULL));

    fscanf(fin,"%d %d\n",&M,&z);
    for(i = 1; i <= M; ++i)
    {
        fscanf(fin,"%c",&Q);
        if(Q == 'I'){
            fscanf(fin,"%d %d\n",&k,&x);
            Insert(R, k-1, x, rand() + 1);
        } else if(Q == 'A'){
            fscanf(fin,"%d\n",&k);
            fprintf(fout,"%d\n", Search(R, k));
        } else if(Q == 'R'){
            fscanf(fin,"%d %d\n",&x,&y);
            Reverse(x,y);
        } else {
            fscanf(fin,"%d %d\n",&x,&y);
            Delete(x,y);
        }
    }

    Inorder(R);
    for(int i = 0; i < v.size(); ++i) fprintf(fout,"%d ",v[i]);


return 0;
}