#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
const char iname[] = "zeap.in";
const char oname[] = "zeap.out";
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
class Treap {
private:
class Node {
public:
static const int infinity = int(1e9);
int key, pr, max_val, min_val, min_diff;
Node *left, *right;
Node(const int _key) {
key = _key, pr = rand() + 1, max_val = min_val = key, min_diff = infinity;
left = right = NULL;
}
void update(void) ;
};
void insert(Node *&, Node *const &) ;
void erase(Node *&, const int ) ;
int find(Node *, const int );
void rotleft(Node *&) ;
void rotright(Node *&) ;
void balance(Node *&) ;
public:
Node *R;
Treap(): R(NULL) {
srand(unsigned(time(NULL)));
}
void insert(const int key) {
Node *p = new Node(key);
insert(R, p);
}
int erase(const int key) {
if (!find(R, key)) return 0;
erase(R, key);
return 1;
}
int find(const int key) {
return find(R, key);
}
int MaxDiff(void) {
if (!R || (!R->left && !R->right)) return -1;
return R->max_val - R->min_val;
}
int MinDiff(void) {
if (!R || (!R->left && !R->right)) return -1;
return R->min_diff;
}
void update(Node *&n) { n->update(); }
};
void Treap::erase(Node *&n, const int key) { // key e sigur in treap
if (key < n->key)
erase(n->left, key);
else if (key > n->key)
erase(n->right, key);
else {
int cache = ((n->left) ? 1 : 0) + ((n->right) ? 1 : 0);
if (cache == 2)
(n->left->pr > n->right->pr) ? rotleft(n) : rotright(n);
else if (cache == 1)
(n->left) ? rotleft(n) : rotright(n);
else
delete n, n = NULL;
if (n != NULL) erase(n, key);
}
if (n != NULL) update(n);
}
void Treap::insert(Node *&n, Node *const &p) {
if (n == NULL) {
n = p;
return ;
}
if (p->key < n->key)
insert(n->left, p);
else if (p->key > n->key)
insert(n->right, p);
balance(n);
}
void Treap::rotleft(Node *&n) {
Node *p = n->left; n->left = p->right, p->right = n, update(n), update(p), n = p;
}
void Treap::rotright(Node *&n) {
Node *p = n->right; n->right = p->left, p->left = n, update(n), update(p), n = p;
}
void Treap::balance(Node *&n) {
if (n->left && n->pr < n->left->pr)
rotleft(n);
else if (n->right && n->pr < n->right->pr)
rotright(n);
update(n);
}
int Treap::find(Node *n, const int key) {
if (n == NULL) return 0;
if (key < n->key) return find(n->left, key);
if (key > n->key) return find(n->right, key);
return 1;
}
void Treap::Node::update(void) {
max_val = min_val = key;
if (left)
max_val = Max(max_val, left->max_val), min_val = Min(min_val, left->min_val);
if (right)
max_val = Max(max_val, right->max_val), min_val = Min(min_val, right->min_val);
min_diff = int(1e9);
if (left)
min_diff = Min(min_diff, left->min_diff), min_diff = Min(min_diff, key - left->max_val);
if (right)
min_diff = Min(min_diff, right->min_diff), min_diff = Min(min_diff, right->min_val - key);
}
int main(void)
{
ifstream in(iname); ofstream out(oname);
Treap T;
for (string s, str; getline(in, s); ) {
istringstream iss(s);
int n;
iss >> str;
if (str == "I")
iss >> n, T.insert(n);
else if (str == "S") {
iss >> n;
if (!T.erase(n)) out << -1 <<'\n';
}
else if (str == "C")
iss >> n, out << T.find(n) <<'\n';
else if (str == "MAX")
out << T.MaxDiff() <<'\n';
else if (str == "MIN")
out << T.MinDiff() <<'\n';
}
in.close(), out.close();
return 0;
}