Cod sursa(job #1834092)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 23 decembrie 2016 20:42:48
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.39 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cctype>
#define INF 2000000000
FILE*fi,*fout;
inline int getmax(int a,int b){
   if(a<b) return b;
   return a;
}
inline int getmin(int a,int b){
   if(a<b) return a;
   return b;
}
char str[4];
char ch;
inline void nextch(){
   while(isdigit(ch)==0)
     ch=fgetc(fi);
}
inline void read(){
   int n=0;
   while(isalpha(ch)){
      str[++n]=ch;
      ch=fgetc(fi);
   }
}
inline int getnr(){
   int nr=0;
   nextch();
   while(isdigit(ch)){
      nr=nr*10+ch-'0';
      ch=fgetc(fi);
   }
   return nr;
}
struct Treap{
   int key,prio;
   int size;
   int max,min,dif;
   Treap *left;
   Treap *right;
   Treap(int _key){
      key=_key;
      prio=rand();
      size=1;
      max=min=_key;
      dif=INF;
      left=right=NULL;
   }
};
Treap *T=NULL;
Treap *insert(Treap *,int);
Treap *balance(Treap *);
Treap *rot_left(Treap *);
Treap *rot_right(Treap *);
inline void refresh(Treap *);
Treap *insert(Treap *nod,int key){
    if(nod==NULL){
       nod=new Treap(key);
       return nod;
    }
    if(nod->key>=key)
      nod->left=insert(nod->left,key);
    if(nod->key<key)
     nod->right=insert(nod->right,key);
    return balance(nod);
}
Treap *balance(Treap *nod){
   if(nod->left!=NULL&&nod->left->prio>nod->prio)
      return rot_right(nod);
   if(nod->right!=NULL&&nod->right->prio>nod->prio)
      return rot_left(nod);
   refresh(nod);
   return nod;
}
Treap *rot_left(Treap *nod){
   Treap *aux;
   aux=nod->right;
   nod->right=aux->left;
   aux->left=nod;
   refresh(nod);
   refresh(aux);
   return aux;
}
Treap *rot_right(Treap *nod){
   Treap *aux;
   aux=nod->left;
   nod->left=aux->right;
   aux->right=nod;
   refresh(nod);
   refresh(aux);
   return aux;
}
inline void refresh(Treap *nod){
   nod->size=1;
   nod->dif=INF;
   nod->max=nod->min=nod->key;
   if(nod->left!=NULL){
      nod->size+=nod->left->size;
      nod->max=getmax(nod->max,nod->left->max);
      nod->min=getmin(nod->min,nod->left->min);
      nod->dif=getmin(nod->dif,nod->key-nod->left->max);
      nod->dif=getmin(nod->dif,nod->left->dif);
   }
   if(nod->right!=NULL){
      nod->size+=nod->right->size;
      nod->max=getmax(nod->max,nod->right->max);
      nod->min=getmin(nod->min,nod->right->min);
      nod->dif=getmin(nod->dif,nod->right->min-nod->key);
      nod->dif=getmin(nod->dif,nod->right->dif);
   }
}
Treap *erase(Treap *nod,int key){
   if(nod->key==key){
      Treap *aux;
      if(nod->left==NULL&&nod->right==NULL){
          delete nod;
          return NULL;
      }
      if(nod->left==NULL){
          aux=rot_left(nod);
          aux->left=erase(aux->left,key);
      }
      else if(nod->right==NULL){
          aux=rot_right(nod);
          aux->right=erase(aux->right,key);
      }
      else if(nod->right->prio>nod->left->prio){
          aux=rot_left(nod);
          aux->left=erase(aux->left,key);
      }
      else{
          aux=rot_right(nod);
          aux->right=erase(aux->right,key);
      }
      return balance(aux);
   }
   else{
      if(nod->key>key)
        nod->left=erase(nod->left,key);
      if(nod->key<key)
        nod->right=erase(nod->right,key);
      return balance(nod);
   }
}
bool find(Treap *nod,int key){
   if(nod==NULL)
     return 0;
   if(nod->key==key)
     return 1;
   if(nod->key>key)
     return find(nod->left,key);
   if(nod->key<key)
     return find(nod->right,key);
}
inline int getSize(Treap *nod){
   if(nod==NULL)
     return 0;
   return nod->size;
}
int main(){
    int key;
    fi=fopen("zeap.in" ,"r");
    fout=fopen("zeap.out" ,"w");
    ch=fgetc(fi);
    while(ch!=EOF){
       read();
       if(str[1]!='M')
         key=getnr();
       if(str[1]=='I'){
          if(find(T,key)==0)
            T=insert(T,key);
       }
       if(str[1]=='S'){
          if(find(T,key)==1)
            T=erase(T,key);
          else
            fprintf(fout,"-1\n");
       }
       if(str[1]=='C')
          fprintf(fout,"%d\n" ,find(T,key));
       if(str[1]=='M'){
          if(getSize(T)<2)
            fprintf(fout,"-1\n");
          else
            if(str[3]=='X')
              fprintf(fout,"%d\n" ,T->max-T->min);
            else
              fprintf(fout,"%d\n" ,T->dif);
       }
       ch=fgetc(fi);
    }
    fclose(fi);
    fclose(fout);
    return 0;
}