Cod sursa(job #1833229)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 21 decembrie 2016 22:12:21
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.05 kb
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <ctime>
#define INF 2000000000
FILE*fi,*fout;
char a;
inline int getnr(){
    int nr=0;
    while(isdigit(a)){
       nr=nr*10+a-'0';
       a=fgetc(fi);
    }
    return nr;
}
inline int getmin(int a,int b){
   if(a<b) return a;
   return b;
}
inline int getmax(int a,int b){
   if(a<b) return b;
   return a;
}
struct Treap{
   int val;
   int prio;
   int size;
   int dif;
   int max;
   int min;
   Treap *left;
   Treap *right;
   Treap(int _val){
      val=_val;
      prio=rand();
      size=1;
      dif=INF;
      max=min=_val;
      left=right=NULL;
   }
};
Treap* insert(Treap *,int);
Treap* balance(Treap *);
Treap* rot_right(Treap *);
Treap* rot_left(Treap *);
Treap* erase(Treap *,int);
inline void refresh(Treap *);
int query(Treap *,int);
int count(Treap *,int);
inline int Size(Treap *);
Treap *T=NULL;
Treap* insert(Treap *nod,int val){
    if(nod==NULL){
       nod=new Treap(val);
       return nod;
    }
    if(val<=nod->val)
       nod->left=insert(nod->left,val);
    else
       nod->right=insert(nod->right,val);
    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_right(Treap *nod){
    Treap *aux;
    aux=nod->left;
    nod->left=aux->right;
    aux->right=nod;
    refresh(nod);
    refresh(aux);
    return aux;
}
Treap* rot_left(Treap *nod){
    Treap *aux;
    aux=nod->right;
    nod->right=aux->left;
    aux->left=nod;
    refresh(nod);
    refresh(aux);
    return aux;
}
Treap* erase(Treap *nod,int val){
    if(nod->val==val){
       Treap *aux;
       if(nod->left==NULL&&nod->right==NULL){
          delete nod;
          return NULL;
       }
       else if(nod->left==NULL){
          aux=rot_left(nod);
          aux->left=erase(aux->left,val);
       }
       else if(nod->right==NULL){
          aux=rot_right(nod);
          aux->right=erase(aux->right,val);
       }
       else if(nod->right->prio>nod->left->prio){
          aux=rot_left(nod);
          aux->left=erase(aux->left,val);
       }
       else{
          aux=rot_right(nod);
          aux->right=erase(aux->right,val);
       }
       return balance(aux);
    }
    else{
       if(nod->val>val)
         nod->left=erase(nod->left,val);
       else
         nod->right=erase(nod->right,val);
       return balance(nod);
    }
}
inline void refresh(Treap *nod){
    nod->size=1;
    nod->dif=INF;
    nod->max=nod->val;
    nod->min=nod->val;
    if(nod->left!=NULL){
      nod->size+=nod->left->size;
      nod->dif=getmin(nod->dif,nod->left->dif);
      nod->dif=getmin(nod->dif,nod->val-nod->left->max);
      nod->max=getmax(nod->max,nod->left->max);
      nod->min=getmin(nod->min,nod->left->min);
    }
    if(nod->right!=NULL){
      nod->size+=nod->right->size;
      nod->dif=getmin(nod->dif,nod->right->dif);
      nod->dif=getmin(nod->dif,nod->right->min-nod->val);
      nod->max=getmax(nod->max,nod->right->max);
      nod->min=getmin(nod->min,nod->right->min);
    }
}
bool find(Treap *nod,int val){
    if(nod==NULL)
       return 0;
    if(nod->val==val)
      return 1;
    if(nod->val>val)
       return find(nod->left,val);
    else
       return find(nod->right,val);
}
int query(Treap *nod,int k){
    if(nod->left==NULL){
       if(k==1)
          return nod->val;
       return query(nod->right,k-1);
    }
    else{
       if(nod->left->size>=k)
         return query(nod->left,k);
       if(nod->left->size+1==k)
         return nod->val;
       return query(nod->right,k-nod->left->size-1);
    }
}
inline int Size(Treap *nod){
   if(nod==NULL)
      return 0;
   return nod->size;
}
int main(){
    int val,x,y,it;
    fi=fopen("zeap.in" ,"r");
    fout=fopen("zeap.out" ,"w");
    srand(time(0));
    a=fgetc(fi);
    while(isalpha(a)){
       if(a=='I'){
         fgetc(fi);
         a=fgetc(fi);
         val=getnr();
         if(find(T,val)==0)
           T=insert(T,val);
       }
       else if(a=='S'){
         fgetc(fi);
         a=fgetc(fi);
         val=getnr();
         if(find(T,val)==1)
            T=erase(T,val);
         else
            fprintf(fout,"-1\n");
       }
       else if(a=='C'){
         fgetc(fi);
         a=fgetc(fi);
         val=getnr();
         fprintf(fout,"%d\n" ,find(T,val));
       }
       else if(a=='M'){
          fgetc(fi);
          a=fgetc(fi);
          if(a=='X')
            if(Size(T)<=1)
              fprintf(fout,"-1\n");
            else
              fprintf(fout,"%d\n" ,T->max-T->min);
          else
            if(Size(T)<=1)
              fprintf(fout,"-1\n");
            else
              fprintf(fout,"%d\n" ,T->dif);
          a=fgetc(fi);
       }
       while(a!=EOF&&isalpha(a)==0)
          a=fgetc(fi);
    }
    fclose(fi);
    fclose(fout);
    return 0;
}