Cod sursa(job #129748)

Utilizator stef2nStefan Istrate stef2n Data 30 ianuarie 2008 01:42:44
Problema Zeap Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.79 kb
#include <stdio.h>
#include <string.h>

#define infile "zeap.in"
#define outfile "zeap.out"
#define DMAX 300005
#define INF 1500000000
struct operatie{char type; int value,pos;};
// type = tipul operatiei
// value = valoarea numerica ce succeda operatia
// pos = pozitia pe care ajunge "value"
FILE *fin,*fout;
operatie op[DMAX];
int n; // nr de operatii
int x[DMAX]; // numerele distincte care apar
int ind; // dimensiunea lui x
int cine[DMAX]; // cine[i] = a cata operatie ajunge pe pozitia i in vectorul x

struct NOD{int minim,maxim,difmin; NOD *st,*dr;};
NOD *root;

inline int min(int x, int y)
  {
   return (x<y)?x:y;
  }

inline int max(int x, int y)
  {
   return (x>y)?x:y;
  }

inline int valoare(char cuv[15])
  {
   int val=0,poz=2,lung=strlen(cuv);
   while(poz<lung && cuv[poz]>='0' && cuv[poz]<='9')
        val=val*10+(cuv[poz++]-'0');
   return val;
  }

void citire()
  {
   char cuv[15];
   n=ind=0;
   fin=fopen(infile,"r");
   while(fgets(cuv,15,fin))
         switch(cuv[0])
              {
               case 'I': op[n].type=0;
                         op[n].value=valoare(cuv);
                         op[n].pos=ind;
                         x[ind]=op[n].value;
                         cine[ind]=n;
                         n++;
                         ind++;
                         break;
               case 'S': op[n].type=1;
                         op[n].value=valoare(cuv);
                         op[n].pos=ind;
                         x[ind]=op[n].value;
                         cine[ind]=n;
                         n++;
                         ind++;
                         break;
               case 'C': op[n].type=2;
                         op[n].value=valoare(cuv);
                         op[n].pos=ind;
                         x[ind]=op[n].value;
                         cine[ind]=n;
                         n++;
                         ind++;
                         break;
               case 'M': if(cuv[1]=='A')
                           op[n].type=3;
                         else
                           op[n].type=4;
                         n++;
                         break;
              }
   fclose(fin);
  }

int pos(int li, int ls)
  {
   int i=0,j=-1,aux;
   while(li<ls)
       {
        if(x[li]>=x[ls])
          {
           op[cine[li]].pos=ls; op[cine[ls]].pos=li;
           aux=cine[li]; cine[li]=cine[ls]; cine[ls]=aux;
           aux=x[li]; x[li]=x[ls]; x[ls]=aux;
           aux=i; i=-j; j=-aux;
          }
        li+=i;
        ls+=j;
       }
   return li;
  }

void quicksort(int li, int ls)
  {
   if(li<ls)
     {int k=pos(li,ls);
      quicksort(li,k-1);
      quicksort(k+1,ls);}
  }

void construire_arbore(NOD *(&prim), int li, int ls)
  {
   prim=new NOD;
   prim->st=NULL;
   prim->dr=NULL;
   if(li==ls)
     {prim->minim=INF;
      prim->maxim=-1;
      prim->difmin=INF;}
   else
     {
      construire_arbore(prim->st,li,(li+ls)/2);
      construire_arbore(prim->dr,(li+ls)/2+1,ls);
      prim->minim=min(prim->st->minim,prim->dr->minim);
      prim->maxim=max(prim->st->maxim,prim->dr->maxim);
      prim->difmin=min(prim->st->difmin,prim->dr->difmin);
      if(prim->st->maxim!=-1 && prim->dr->minim!=INF)
        prim->difmin=min(prim->difmin,prim->dr->minim-prim->st->maxim);
     }
  }

void insereaza(NOD *(&prim), int li, int ls, int poz, int val)
  {
   if(li==ls)
     {
      prim->minim=val;
      prim->maxim=val;
     }
   else
     {if(poz<=(li+ls)/2)
        insereaza(prim->st,li,(li+ls)/2,poz,val);
      else
        insereaza(prim->dr,(li+ls)/2+1,ls,poz,val);
      prim->minim=min(prim->st->minim,prim->dr->minim);
      prim->maxim=max(prim->st->maxim,prim->dr->maxim);
      prim->difmin=min(prim->st->difmin,prim->dr->difmin);
      if(prim->st->maxim!=-1 && prim->dr->minim!=INF)
        prim->difmin=min(prim->difmin,prim->dr->minim-prim->st->maxim);}
  }

int sterge(NOD *(&prim), int li, int ls, int poz, int val)
  {
   if(li==ls)
     if(prim->minim==val)
       {prim->minim=INF;
        prim->maxim=-1;
        return 0;}
     else
       return -1;
   else
     {if(poz<=(li+ls)/2)
        {if(sterge(prim->st,li,(li+ls)/2,poz,val)==-1)
           return -1;}
      else
        {if(sterge(prim->dr,(li+ls)/2+1,ls,poz,val)==-1)
           return -1;}
      prim->minim=min(prim->st->minim,prim->dr->minim);
      prim->maxim=max(prim->st->maxim,prim->dr->maxim);
      prim->difmin=min(prim->st->difmin,prim->dr->difmin);
      if(prim->st->maxim!=-1 && prim->dr->minim!=INF)
        prim->difmin=min(prim->difmin,prim->dr->minim-prim->st->maxim);
      return 0;}
  }

int cauta(NOD *(&prim), int li, int ls, int poz, int val)
  {
   if(li==ls)
     if(prim->minim==val)
       return 1;
     else
       return 0;
   else
     if(poz<=(li+ls)/2)
       return cauta(prim->st,li,(li+ls)/2,poz,val);
     else
       return cauta(prim->dr,(li+ls)/2+1,ls,poz,val);
  }


int main()
{
int i;
citire();
quicksort(0,ind-1);

for(i=1;i<ind;i++)
   if(x[i]==x[i-1])
     op[cine[i]].pos=op[cine[i-1]].pos;

construire_arbore(root,0,ind-1);

fout=fopen(outfile,"w");
for(i=0;i<n;i++)
   switch(op[i].type)
        {
         case 0: insereaza(root,0,ind-1,op[i].pos,op[i].value);
                 break;
         case 1: if(sterge(root,0,ind-1,op[i].pos,op[i].value)==-1)
                   fprintf(fout,"-1\n");
                 break;
         case 2: fprintf(fout,"%d\n",cauta(root,0,ind-1,op[i].pos,op[i].value));
                 break;
         case 3: if(root->maxim!=-1 && root->minim!=INF && root->maxim!=root->minim)
                   fprintf(fout,"%d\n",root->maxim-root->minim);
                 else
                   fprintf(fout,"-1\n");
                 break;
         case 4: if(root->difmin==INF)
                   fprintf(fout,"-1\n");
                 else
                   fprintf(fout,"%d\n",root->difmin);
                 break;
        }
fclose(fout);
return 0;
}