#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;
}