Cod sursa(job #2021287)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 13 septembrie 2017 08:47:52
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.01 kb
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
ifstream f("hashuri.in");
ofstream g("hashuri.out");
int N;
struct Treap
{
    int key, priority, size;
    Treap * left, *right;
    Treap(int size, int key, int  priority, Treap * left, Treap * right)
    {
        this -> size = size;
        this -> key = key;
        this -> priority = priority;
        this -> left = left;
        this -> right = right;
    }
};
Treap * R, *Nil;

void Update(Treap *& Node)
{
    if(Node == Nil)
        return;
    Node -> size = Node -> left -> size + Node -> right -> size + 1;
}
void RotLeft(Treap *& Node)
{
    Treap * T = Node -> left;
    Node -> left = T -> right;
    T -> right = Node;
    Node = T;
    Update(Node -> right);
    Update(Node);
}
void RotRight(Treap *& Node)
{
    Treap * T = Node -> right;
    Node -> right = T -> left;
    T -> left = Node;
    Node = T;
    Update(Node -> left);
    Update(Node);
}
void Balance(Treap *&Node)
{
    if(Node -> left -> priority > Node -> priority)
        RotLeft(Node);
    else
        if(Node -> right -> priority > Node -> priority)
            RotRight(Node);
}

void Insert(Treap *& Node, int Key, int Priority)
{
    if(Node == Nil)
    {
        Node = new Treap(1, Key, Priority, Nil, Nil);
        return;
    }
    if(Key <= Node -> key)
        Insert(Node -> left, Key, Priority);
    else
        Insert(Node -> right, Key, Priority);
    Update(Node);
    Balance(Node);
}

void Erase(Treap *& Node)
{
    if(Node -> left == Nil && Node -> right == Nil)
    {
        delete Node, Node = Nil;
        return;
    }
    if(Node -> left -> priority >= Node -> right -> priority)
        RotLeft(Node);
    else
        RotRight(Node);
    if(Node -> left -> priority == -1)
        Erase(Node -> left);
    else
        Erase(Node -> right);
}

void Split(Treap *& Root, Treap *& NewRoot, int Key)
{

    Insert(Root, Key, (1 << 31) - 1);
    Treap * T = Root;
    Root = T -> left;
    NewRoot = T -> right;
    delete T;
}
Treap * Join(Treap*& T1, Treap *& T2)
{
    Treap * NewR = new Treap(T1 -> size + T2 -> size + 1, 0, -1, T1, T2);
    Erase(NewR);
    return NewR;
}

void Erase(Treap *& Root, int Left, int Right)
{
    Treap * A = Root, *B, *C;
    Split(A, B, Left);
    Split(B, C, Right + 1);
    Root = Join(A, C);
}
bool Find(Treap *& Node, int Key)
{
    if(Node == Nil)
        return 0;
    if(Node -> key == Key)
        return 1;
    if(Key < Node -> key)
        return Find(Node -> left, Key);
    else
        return Find(Node -> right, Key);
}
int main()
{
    R = Nil = new Treap(0, 0, 0, NULL, NULL);
    int N;
    f >> N;
    srand(time(NULL));
    for(int i = 1; i <= N; i++)
    {
        int type, x;
        f >> type >> x;
        if(type == 1)
            Insert(R, x, rand() + 1);
        if(type == 2)
            Erase(R, x, x);
        if(type == 3)
            g << Find(R, x) << "\n";
    }
    return 0;
}