Cod sursa(job #2656551)

Utilizator nicolaefilatNicolae Filat nicolaefilat Data 7 octombrie 2020 23:03:49
Problema Zeap Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.93 kb
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <set>
#include <time.h>

using namespace std;

ifstream in("abce.in");
ofstream out("abce.out");

struct Nod{
    int valoare,prioritate;
    Nod *st,*dr;
    Nod(){

    }
    Nod(int val,int p){
        valoare = val;
        prioritate = p;
        st = nullptr;
        dr = nullptr;
    }
};
class Treap{
public:
    Nod *radacina;

    Treap(){
        radacina = nullptr;
    }

    void insereaza(Nod *& nod,int val){
        if(nod == nullptr){
            int p = rand() % 100;
            //cout<<"Am inserat "<<val<<" cu prioritate "<<p<<"\n";
            nod = new Nod(val,p);
            return;
        }
        if(nod->valoare < val){
            insereaza(nod->dr,val);
            if(nod->prioritate < nod->dr->prioritate)
                leftRotate(nod);
        }
        else{
            insereaza(nod->st,val);
            if(nod->prioritate < nod->st->prioritate)
                rightRotate(nod);
        }
    }
    Nod *gaseste(Nod *nod,int val){
        if(nod == nullptr)
            return nod;
        if(nod->valoare < val)
            return gaseste(nod->dr,val);
        else if(nod->valoare > val)
            return gaseste(nod->st,val);
        else
            return nod;
    }
    int lowerBound(Nod *nod, int val){
        if(nod->valoare < val){
            if(nod->dr != nullptr)
                return lowerBound(nod->dr,val);
            return 2e9;
        }
        else if(nod->valoare > val){
            if(nod->st != nullptr)
                return min(nod->valoare,lowerBound(nod->st,val));
            return nod->valoare;
        }
        else
            return nod->valoare;
    }
    int upperBound(Nod *nod, int val){
        if(nod->valoare < val){
            if(nod->dr != nullptr)
                return max(nod->valoare,upperBound(nod->dr,val));
            return nod->valoare;
        }else if(nod->valoare > val){
            if(nod->st != nullptr)
                return upperBound(nod->st,val);
            return -2e9;
        }else
            return nod->valoare;
    }
    void sterge(Nod *& nod,int val){
        if(nod == nullptr)
            return;
        //cout<<"sunt pe nodul "<<nod->valoare<<endl;
        if(nod->valoare == val){
            if(nod->st != nullptr && nod->dr != nullptr){
                if(nod->st->prioritate > nod->dr->prioritate)
                    rightRotate(nod);
                else
                    leftRotate(nod);
            }else if(nod->st != nullptr){
                //cout<<"Right rotate"<<endl;
                rightRotate(nod);
            }
            else if(nod->dr != nullptr){
                leftRotate(nod);
                //cout<<"Left rotate"<<endl;
            }
            else if(nod->valoare == val){
                //cout<<"Am sters nodul cautat "<<nod->valoare<<endl;
                nod = nullptr;
            }
            if(nod == nullptr)
                return;
            //cout<<"=> \n";
            //afisare();
            //cout<<"Nodul este acum "<<nod->valoare<<endl;


        }
        if(nod->valoare < val){
            sterge(nod->dr,val);
        }else if(nod->valoare > val)
            sterge(nod->st,val);
    }

    void afisare(bool detailed = true){
        inordine(radacina,detailed);
        cout<<"======="<<endl;
    }
    void afisare_intre_valori(Nod *nod, int minim,int maxim){
        if(nod == nullptr)
            return;
        afisare_intre_valori(nod->st,minim,maxim);
        if(nod->valoare >= minim && nod->valoare <= maxim)
            out<<nod->valoare<<" ";
        afisare_intre_valori(nod->dr,minim,maxim);
    }

private:
    void inordine(Nod *r,bool detailed){
        if(r == nullptr)
            return;
        if(detailed)
            cout<<"Nodul : "<<r->valoare<<" cu prioritate : "<<r->prioritate<<" | ";
        else
            cout<<r->valoare;
        if(detailed)
            cout<<"\n";
        else
            cout<<" ";
        inordine(r->st,detailed);
        inordine(r->dr,detailed);
    }
    void leftRotate(Nod *& t){
        Nod *fiu = t->dr;
        t->dr = fiu->st;
        fiu->st = t;
        t = fiu;
    }
    void rightRotate(Nod *& t){
        Nod *fiu = t->st;
        t->st = fiu->dr;
        fiu->dr = t;
        t = fiu;
    }

};

set<int>v;

int mic(int x ){
    for(auto element : v){
        if(element >= x)
            return element;
    }
    return 2e9;
}
int mare(int x){
    int raspuns = -2e9;
    for(auto element : v){
        if(element <= x)
            raspuns = element;
    }
    return raspuns;
}
void generare_random(){
    int q = 10000;
    srand(time(0));
    Treap treap;

    for(int i = 1; i <= q; i++){
        int op,x;
        x = (rand() % (int) 2e9) - 1e3;

        op = rand() % 3;
        if(op == 2)
            op = 1;
        else
            op += 4;
        if(op == 1){
            treap.insereaza(treap.radacina,x);
            v.insert(x);
        }
        else if(op == 3){
            if(treap.gaseste(treap.radacina,x) != nullptr)
                out<<1<<"\n";
            else
                out<<0<<"\n";
        }else if(op == 5){
            if(v.size() && mic(x) != treap.lowerBound(treap.radacina,x)){
                for(auto el : v)
                    out<<el<<" ";
                out<<"\nCel mai mic numar >= "<<x<<" e "<<treap.lowerBound(treap.radacina,x)<<" "<<mic(x)<<"\n";
            }
        }
        else if(op == 4){
            if(v.size() && mare(x) != treap.upperBound(treap.radacina,x)){
                for(auto el : v)
                    out<<el<<" ";
                out<<"\nCel mai mare numar <= "<<x<<" e "<<treap.upperBound(treap.radacina,x)<<" "<<mare(x)<<"\n";
            }
        }
    }
}

int main()
{

    Treap treap;

    int q;
    in>>q;
    for(int i = 1; i <= q; i++){
        int op,x;
        in>>op>>x;

        if(op == 1){
            treap.insereaza(treap.radacina,x);
            //treap.afisare();
            v.insert(x);
        }
        else if(op == 2){
            //cout<<"Vreau sa sterg nodul "<<x<<endl;
            treap.sterge(treap.radacina,x);
            //treap.afisare();
            v.erase(x);
        }
        else if(op == 3){
            //cout<<"Caut nodul "<<x<<endl;
            //treap.afisare();
            if(treap.gaseste(treap.radacina,x) != nullptr)
                out<<1<<"\n";
            else
                out<<0<<"\n";
        }else if(op == 5){
            out<<treap.lowerBound(treap.radacina,x)<<"\n";
        }
        else if(op == 4){
            out<<treap.upperBound(treap.radacina,x)<<"\n";
        }
        else if(op == 6){
            int y;
            in>>y;
            treap.afisare_intre_valori(treap.radacina,x,y);
            out<<"\n";
        }
    }
    return 0;
}