Pagini recente » Cod sursa (job #186648) | Cod sursa (job #1123582) | Cod sursa (job #2882205) | Cod sursa (job #1070881) | Cod sursa (job #1747332)
#include <bits/stdc++.h>
using namespace std;
multiset < int > St;
#define INEXISTENT 0
struct item
{
int key, prior;
item * l, * r;
item(){}
item(int key) : key(key), prior((rand()<<16) ^ rand()), l(NULL), r(NULL) {}
};
using pitem = item *;
pitem root;
void split(pitem t, int x, pitem& l, pitem& r)
{
if (!t)
l = r = NULL;
else if (x >= t->key)
split(t->r, x, t->l, r), l = t;
else split(t->l,x, l, t->r), r = t;
}
void merge(pitem& t, pitem l, pitem r)
{
if (!l || !r)
t = l ? l : r;
else if (l->prior >= r->prior)
merge(l->r, l->r, r), t = l;
else merge(r->l, l, r->l), t = r;
}
int MAX(pitem t)
{
while(t->r) t = t->r;
return t->key;
}
int MIN(pitem t)
{
while(t->l) t = t->l;
return t->key;
}
vector<pitem> findPath(pitem t)
{
int key = t->key;
pitem tmp = root;
vector<pitem> rt;
while(tmp->key != key)
{
rt.push_back(tmp);
if (key <= tmp->key)
tmp = tmp->l;
else
tmp = tmp->r;
}
rt.push_back(t);
reverse(rt.begin(),rt.end());
return rt;
}
int inorder_next(pitem t)
{
int mx = MAX(root);
if (t->key == mx)
return INEXISTENT;
if (t->r)
return MIN(t->r);
else {
vector<pitem> vt = findPath(t);
for(int i=1;i<vt.size();i++){
if (vt[i]->l->key == vt[i-1]->key)
return vt[i]->key;
}
}
}
int inorder_prev(pitem t)
{
int mn = MIN(root);
if (t->key == mn)
return INEXISTENT;
if (t->l)
return MAX(t->l);
vector<pitem> vt = findPath(t);
for(int i=1;i<vt.size();i++){
if (vt[i]->r->key == vt[i-1]->key)
return vt[i]->key;
}
}
void calc(pitem t, int tip = 1)
{
if (tip)
{
int next = inorder_next(t);
if (next != INEXISTENT) St.insert(next - t->key);
int prev = inorder_prev(t);
if (prev != INEXISTENT) St.insert(t->key - prev);
if (next != INEXISTENT && prev != INEXISTENT)
St.erase(St.find(next - prev));
} else {
int next = inorder_next(t);
if (next != INEXISTENT) St.erase(St.find(next - t->key));
int prev = inorder_prev(t);
if (prev != INEXISTENT) St.erase(St.find(t->key - prev));
if (next != INEXISTENT && prev != INEXISTENT)
St.insert(next - prev);
}
}
void insert(pitem& t, pitem it)
{
if (!t)
t = it, calc(it);
else if (it->prior > t->prior)
split(t, it->key, it->l, it->r), t = it, calc(it);
else
insert(it->key < t->key ? t->l : t->r , it);
}
int erase(pitem& t, int key)
{
if (!t)
return -1;
if (t->key == key) {
calc(t, 0);
return merge(t, t->l, t->r), 1;
}
else
return erase(key <= t->key ? t->l : t->r, key);
}
int find(pitem t, int key)
{
if (!t)
return 0;
if (t->key == key)
return 1;
return find(key <= t->key ? t->l : t->r, key);
}
int cnt = 0;
int main()
{
srand(time(NULL));
string c;
ifstream fin("zeap.in");
ofstream fout("zeap.out");
while (fin >> c)
{
// fout << c << endl;
if (c == "I") {
int val;
fin>>val;
cnt += !find(root, val);
insert(root, new item(val));
}
if (c == "S"){
int val;
fin>>val;
if (erase(root, val)==-1)
fout << "-1\n";
else cnt -= 1;
}
if (c == "C"){
int val;
fin>>val;
fout << find(root, val) << '\n';
}
if (c == "MAX"){
if (cnt < 2) {
cout << "-1\n";
continue;
}
fout << MAX(root) - MIN(root) << "\n";
}
if (c == "MIN"){
if (cnt < 2) {
cout << "-1\n";
continue;
}
if (St.size())
fout << *St.begin() << '\n';
}
}
}