Pagini recente » Cod sursa (job #2329360) | Cod sursa (job #2315358) | Cod sursa (job #2442322) | Cod sursa (job #1011098) | Cod sursa (job #2656943)
#include <iostream>
#include <fstream>
#include <time.h>
#include <cstdlib>
using namespace std;
fstream in("zeap.in");
ofstream out("zeap.out");
typedef long long ll;
ll maxim(ll a,ll b){
if(a > b)
return a;
return b;
}
ll minim(ll a,ll b){
if(a < b)
return a;
return b;
}
ll min(ll a,ll b,ll c = 2e9){
return minim(a,minim(b,c));
}
ll max(ll a,ll b,ll c = -2e9){
return maxim(a,maxim(b,c));
}
struct Nod{
ll val;
int prioritate;
Nod *st,*dr;
ll minim,maxim;
ll diferentaMinima;
Nod(){
st = dr = nullptr;
prioritate = rand() % 100;
val = 0;
minim = 2e9;
maxim = -2e9;
diferentaMinima = 2e9;
}
Nod(int valoare,Nod *nul){
st = dr = nul;
prioritate = rand() % 100000;
val = minim = maxim = valoare;
diferentaMinima = 2e9;
}
};
Nod *NIL = new Nod();
/// treap cu prioritati de heap de maxim, radacina are cea mai mare prioritate
class Zeap{
public:
int elemente = 0;
Zeap(){
radacina = NIL;
}
void insert(int val,int p = -1){
insereaza(radacina,val,p);
}
void erase(int val){
sterge(radacina,val);
}
Nod *find(int val){
return gaseste(radacina,val);
}
void print(){
cout<<"Val maxim "<<radacina->maxim<<"\n";
cout<<"Val minim "<<radacina->minim<<"\n";
cout<<"Dif Min "<<radacina->diferentaMinima<<"\n";
afisare(radacina);
cout<<"\n";
}
void debug(bool detailed = true){
cout<<"Val maxim "<<radacina->maxim<<"\n";
cout<<"Val minim "<<radacina->minim<<"\n";
cout<<"Dif Min "<<radacina->diferentaMinima<<"\n";
inordine(radacina,detailed);
cout<<"\n";
}
Nod * radacina = NIL;
private:
void leftRotate(Nod *& tata);
void rightRotate(Nod *& tata);
void update(Nod *& nod);
void insereaza(Nod *& radacina, int val,int prioritate);
void sterge(Nod *& radacina, int val);
Nod* gaseste(Nod * radacina,int val);
void afisare(Nod *radacina);
void inordine(Nod *radacina,bool);
};
void Zeap::update(Nod *& nod){
nod->maxim = max(nod->val,nod->st->maxim,nod->dr->maxim);
nod->minim = min(nod->val,nod->st->minim,nod->dr->minim);
nod->diferentaMinima = min(nod->val - nod->st->maxim,nod->dr->minim - nod->val);
nod->diferentaMinima = min(nod->diferentaMinima,nod->dr->diferentaMinima,nod->st->diferentaMinima);
}
void Zeap::insereaza(Nod *& nod,int val,int prioritate = -1){
if(nod == NIL){
elemente++;
nod = new Nod(val,NIL);
if(prioritate != -1)
nod->prioritate = prioritate;
return;
}
if(nod->val < val){
insereaza(nod->dr,val,prioritate);
/// am inserat in dreapta
if(nod->dr->prioritate > nod->prioritate){
leftRotate(nod);
update(nod->st);
}
}else if(nod->val > val){
insereaza(nod->st,val,prioritate);
if(nod->st->prioritate > nod->prioritate){
rightRotate(nod);
update(nod->dr);
}
}
update(nod);
}
void Zeap::sterge(Nod *& nod,int val){
if(nod == NIL){
return;
}
if(nod->val == val){
if(nod->st != NIL && nod->dr != NIL){
if(nod->st->prioritate > nod->dr->prioritate)
rightRotate(nod);
else
leftRotate(nod);
}else if(nod->st != NIL)
rightRotate(nod);
else if(nod->dr != NIL)
leftRotate(nod);
else{
elemente--;
nod = NIL;
return;
}
}
update(nod);
if(nod->val > val)
sterge(nod->st,val);
else
sterge(nod->dr,val);
update(nod);
}
Nod *Zeap::gaseste(Nod * nod, int val){
if(nod == NIL)
return nod;
if(nod->val > val)
return gaseste(nod->st,val);
else if(nod->val < val)
return gaseste(nod->dr,val);
else
return nod;
}
void Zeap::leftRotate(Nod *& tata){
Nod *fiu = tata->dr; /// il iau pe fiu si il rotesc in stanga
tata->dr = fiu->st;
fiu->st = tata;
tata = fiu; /// sa am pointer-ul intr-o pozitie buna
}
void Zeap::rightRotate(Nod *& tata){
Nod *fiu = tata->st; /// il iau pe fiul stanga si il rotesc in dreapta
tata->st = fiu->dr;
fiu->dr = tata;
tata = fiu;
}
void Zeap::inordine(Nod *r,bool detailed){
if(r == NIL)
return;
if(detailed){
cout<<"Nodul : "<<r->val<<" cu prioritate : "<<r->prioritate<<" | ";
cout<<"Maxim : "<<r->maxim<<" "<<"Minim : "<<r->minim<<" "<<"Dif Min "<<r->diferentaMinima<<"\n";
}
else
cout<<r->val<<" ";
inordine(r->st,detailed);
inordine(r->dr,detailed);
}
void Zeap::afisare(Nod *r){
if(r == NIL)
return;
afisare(r->st);
cout<<r->val<<" ";
afisare(r->dr);
}
void RandomInput(){
/// generez operatii random si vad ca am un timp de executie < 0.5s
/// totusi de ce TLE??? hmmmm
int limit = 300000;
for(int i = 1; i <= limit; i++){
int nr = rand() % int(1e9);
int op = rand() % 5 + 1; /// am 5 operatii
char chr;
if(op == 1)
chr = 'I';
else if(op == 2)
chr = 'S';
else if(op == 3)
chr = 'C';
else if(op == 4)
in<<"MIN";
else
in<<"MAX";
if(op <= 3)
in<<chr<<" "<<nr;
in<<"\n";
}
}
int main()
{
srand(time(0));
in.tie(0);
out.tie(0);
ios::sync_with_stdio(false);
///RandomInput();
Zeap zeap; /// asta nu il fac pointer prea multi pointeri god damn
char prima;
int nr;
while((prima = in.get()) && prima != EOF){
if(prima != 'M')
in>>nr;
if(prima == 'I'){
if(zeap.find(nr) == NIL)
zeap.insert(nr);
}else if(prima == 'S'){
if(zeap.find(nr) == NIL)
out<<-1<<"\n";
else
zeap.erase(nr);
}else if(prima == 'C'){
if(zeap.find(nr) != NIL)
out<<1;
else
out<<0;
out<<"\n";
}else if(prima == 'M'){
in.get(prima);
if(prima == 'I'){
if(zeap.elemente < 2)
out<<-1<<'\n';
else
out<<zeap.radacina->diferentaMinima<<'\n';
}else{
if(zeap.elemente < 2)
out<<-1<<'\n';
else
out<<zeap.radacina->maxim - zeap.radacina->minim<<'\n';
}
in.get(); /// citesc si ultimul I
}
in.get();
}
return 0;
}