#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define INFINITY 1000000001
#define R 524287
#define Nadejde 900000
#define MAX_LEVEL 20
#define Smerenie 3
typedef struct {
int inside, level, bufPtr;
int MIN_VAL, MAX_VAL;
int list[Nadejde];
} sl;
sl set, map;
char s[Smerenie]; // operatia curenta.
int update[MAX_LEVEL]; // folosit in timpul cautarii.
/** abs(X). **/
int ABS(int X) {
return X > 0 ? X : -X;
}
/** Initializeaza structura "skip". **/
void init(sl *skip, int min, int max) {
skip -> MIN_VAL = min;
skip -> MAX_VAL = max;
skip -> list[0] = skip -> MIN_VAL;
skip -> list[MAX_LEVEL + 1] = skip -> MAX_VAL;
int i;
for (i = 1; i <= MAX_LEVEL; i++) {
skip -> list[i] = MAX_LEVEL + 1;
}
skip -> bufPtr = MAX_LEVEL + 2;
skip -> level = 1;
}
/** Da-mi un nivel random. **/
int randomLevel() {
int l = 1, r;
for (r = rand() & R; r & 1; r >>= 1) {
l++;
}
return l;
}
/** Insereaza valoarea "x" in structura "skip", cu restrictia "task". **/
void insert(sl *skip, int x, int task) {
int l, pos = update[0];
int curr = skip -> list[pos + 1];
if ((task) || (skip -> list[curr] != x)) {
int newLevel = randomLevel();
if (newLevel > skip -> level) {
for (l = skip -> level; l < newLevel; l++) {
update[l] = 0;
}
skip -> level = newLevel;
}
skip -> list[skip -> bufPtr] = x;
for (l = 0; l < newLevel; l++) {
skip -> list[skip -> bufPtr + l + 1] = skip -> list[update[l] + l + 1];
skip -> list[update[l] + l + 1] = skip -> bufPtr;
}
skip -> bufPtr += newLevel + 1;
skip -> inside++;
}
}
/** Sterge din structura "skip" valoarea "x". **/
void erase(sl *skip, int x) {
int l, pos = update[0];
/* Refacem acei pointeri care pointeaza la "curr" (restul trec deasupra noastra). */
int curr = skip -> list[pos + 1];
if (skip -> list[curr] == x) {
l = 0;
while ((l < skip -> level) && (skip -> list[update[l] + l + 1] == curr)) {
skip -> list[update[l] + l + 1] = skip -> list[curr + l + 1];
l++;
}
skip -> inside--;
}
}
/** Cauta in structura "skip" valoarea "x". **/
void search(sl *skip, int x) {
int l, pos = 0;
for (l = skip -> level; l >= 0; l--) {
while (skip -> list[skip -> list[pos + l + 1]] < x) {
pos = skip -> list[pos + l + 1];
}
update[l] = pos;
}
}
int main(void) {
srand(time(NULL));
int x, pos, curr, next;
FILE *in = fopen("zeap.in", "r");
FILE *out = fopen("zeap.out", "w");
init(&set, -INFINITY, INFINITY);
init(&map, 0, (INFINITY << 1) + 1);
insert(&map, INFINITY << 1, 0);
map.inside--;
/* Cat timp mai avem instructiuni de efectuat. */
while (fscanf(in, "%s", s) != EOF) {
switch (s[0]) {
/* Inserare. */
case 'I':
/* Citirea datelor. */
fscanf(in, "%d", &x);
/* Pregatirea pozitiilor. */
search(&set, x);
pos = update[0];
next = set.list[pos + 1];
/* Conditiile structurii. */
if (set.list[next] != x) {
/* Insereaza in "set" valoarea "x". */
insert(&set, x, 0);
/* Sterge din "map" valoarea |sl[pos] - sl[next]|. */
search(&map, ABS(set.list[pos] - set.list[next]));
erase(&map, ABS(set.list[pos] - set.list[next]));
/* Insereaza in "map" valoarea |x - sl[pos]|. */
search(&map, ABS(x - set.list[pos]));
insert(&map, ABS(x - set.list[pos]), 1);
/* Insereaza in "map" valoarea |x - sl[next]|. */
search(&map, ABS(x - set.list[next]));
insert(&map, ABS(x - set.list[next]), 1);
}
break;
/* Stergere. */
case 'S':
/* Citirea datelor. */
fscanf(in, "%d", &x);
/* Pregatirea pozitiilor. */
search(&set, x);
pos = update[0];
curr = set.list[pos + 1];
next = set.list[curr + 1];
/* Daca se afla in structura. */
if (set.list[curr] == x) {
/* Sterge din "set" valoarea "x". */
erase(&set, x);
/* Sterge din "map" valoarea |sl[pos] - sl[curr]|. */
search(&map, ABS(set.list[pos] - set.list[curr]));
erase(&map, ABS(set.list[pos] - set.list[curr]));
/* Sterge din "map" valoarea |sl[curr] - sl[next]|. */
search(&map, ABS(set.list[curr] - set.list[next]));
erase(&map, ABS(set.list[curr] - set.list[next]));
/* Insereaza in structura "map" valoarea |sl[pos] - sl[next]|. */
search(&map, ABS(set.list[pos] - set.list[next]));
insert(&map, ABS(set.list[pos] - set.list[next]), 1);
} else {
fprintf(out, "%d\n", -1);
}
break;
/* Cautare. */
case 'C':
/* Citirea datelor. */
fscanf(in, "%d", &x);
/* Pregatirea pozitiilor. */
search(&set, x);
pos = update[0];
/* Afisarea solutiei. */
fprintf(out, "%d\n", (set.list[set.list[pos + 1]] == x));
break;
case 'M':
switch (s[1]) {
/* Diferenta in modul minima. */
case 'I':
/* Afisarea solutiei. */
fprintf(out, "%d\n", set.inside > 1 ? map.list[map.list[1]] : -1);
break;
/* Diferenta in modul maxima. */
case 'A':
/* Afisarea solutiei. */
if (set.inside > 1) {
search(&set, set.MAX_VAL);
fprintf(out, "%d\n", set.list[update[0]] - set.list[set.list[1]]);
} else {
fprintf(out, "-1\n");
}
break;
}
break;
}
}
fclose(in);
fclose(out);
/// Multumim Doamne!
puts("Doamne ajuta!");
return 0;
}