Pagini recente » Cod sursa (job #2857598) | Cod sursa (job #1666343) | Cod sursa (job #1511664) | Cod sursa (job #1149469) | Cod sursa (job #3133445)
//ALEXANDRU MICLEA
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <cmath>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>
#include <chrono>
#include <iostream>
#include <fstream>
#include <array>
using namespace std;
#ifdef INFOARENA
ifstream fin("zeap.in"); ofstream fout("zeap.out");
cin.rdbuf(fin.rdbuf()); cout.rdbuf(fout.rdbuf());
#endif
typedef long long ll;
//VARIABLES
const long long INF = 1e9 + 7;
class RBT {
private:
struct node {
int value;
bool isBlack;
node* left, * right, * dad;
node(node* left, node* right, node* dad, int val = INF, bool isBlack = true) : value(val), isBlack(isBlack) {
this->left = left;
this->right = right;
this->dad = dad;
}
};
node* treeRoot, * NIL;
public:
RBT() {
treeRoot = new node(NULL, NULL, NULL);
NIL = treeRoot;
}
node* search(int);
int inTree(int);
void leftRotate(node*);
void rightRotate(node*);
void insert(int);
void remove(int);
void transplant(node*, node*);
int successor(int);
int predecessor(int);
int sorted(int, int);
void insert_fix_up(node*);
void remove_fix_up(node*);
void redoRoot();
};
//FUNCTIONS
void RBT::rightRotate(node* root) {
assert(root->left != NIL);
node* swap = root->left;
root->left = swap->right;
if (swap->right != NIL) swap->right->dad = root;
swap->dad = root->dad;
if (root == root->dad->left) root->dad->left = swap;
else root->dad->right = swap;
swap->right = root;
root->dad = swap;
}
void RBT::leftRotate(node* root) {
assert(root->right != NIL);
node* swap = root->right;
root->right = swap->left;
if (swap->left != NIL) swap->left->dad = root;
swap->dad = root->dad;
if (root->dad->left == root) root->dad->left = swap;
else root->dad->right = swap;
swap->left = root;
root->dad = swap;
}
void RBT::insert(int val) {
if (treeRoot == NIL) {
treeRoot = new node(NIL, NIL, NIL, val, true);
}
else {
node* pointer = treeRoot;
while (true) {
assert(pointer->value != val);
if (pointer->value > val && pointer->left != NIL) {
pointer = pointer->left;
continue;
}
if (pointer->value < val && pointer->right != NIL) {
pointer = pointer->right;
continue;
}
break;
}
if (pointer->value < val) {
pointer->right = new node(NIL, NIL, pointer, val, false);
insert_fix_up(pointer->right);
}
if (pointer->value > val) {
pointer->left = new node(NIL, NIL, pointer, val, false);
insert_fix_up(pointer->left);
}
}
}
void RBT::redoRoot() {
while (treeRoot->dad != NIL) {
treeRoot = treeRoot->dad;
}
treeRoot->isBlack = true;
}
RBT::node* RBT::search(int val) {
node* pointer = treeRoot;
while (true) {
if (pointer == NIL) return NIL;
if (pointer->value == val) {
return pointer;
}
if (pointer->value > val && pointer->left != NIL) {
pointer = pointer->left;
continue;
}
if (pointer->value < val && pointer->right != NIL) {
pointer = pointer->right;
continue;
}
return NIL;
}
}
int RBT::inTree(int val) {
node* pointer = search(val);
if (pointer != NIL) return 1;
return 0;
}
int RBT::predecessor(int val) {
int ans = -(INF);
node* pointer = treeRoot;
while (pointer != NIL) {
if (pointer->value <= val) {
ans = max(ans, pointer->value);
pointer = pointer->right;
}
else {
pointer = pointer->left;
}
}
return ans;
}
int RBT::successor(int val) {
int ans = INF;
node* pointer = treeRoot;
while (pointer != NIL) {
if (pointer->value >= val) {
ans = min(ans, pointer->value);
pointer = pointer->left;
}
else {
pointer = pointer->right;
}
}
return ans;
}
int RBT::sorted(int st, int dr) {
int val;
ll minn = INF;
if (this->inTree(st)) val = st;
else val = successor(st);
while (val <= dr) {
ll next = successor(val + 1);
minn = min(minn, next - val);
if (next == val) break;
else val = next;
}
return minn;
}
void RBT::insert_fix_up(node* root) {
while (root->dad->isBlack == false) {
node* granddad = root->dad->dad;
assert(granddad != NIL);
if (root->dad == granddad->left) {
if (granddad->right->isBlack == false) {
root->dad->isBlack = true;
granddad->right->isBlack = true;
granddad->isBlack = false;
root = granddad;
}
else {
if (root == root->dad->right) {
root = root->dad;
leftRotate(root);
}
root->dad->isBlack = true;
granddad->isBlack = false;
rightRotate(granddad);
}
}
else {
if (granddad->left->isBlack == false) {
root->dad->isBlack = true;
granddad->left->isBlack = true;
granddad->isBlack = false;
root = granddad;
}
else {
if (root == root->dad->left) {
root = root->dad;
rightRotate(root);
}
root->dad->isBlack = true;
granddad->isBlack = false;
leftRotate(granddad);
}
}
}
redoRoot();
}
void RBT::transplant(node* root, node* replace) {
if (root->dad == NIL) {
treeRoot = replace;
}
else if (root == root->dad->left) {
root->dad->left = replace;
}
else root->dad->right = replace;
replace->dad = root->dad;
}
void RBT::remove(int val) {
node* child = NIL;
node* z = search(val);
if (z == NIL){
cout << "-1\n";
return;
}
node* y = z;
bool origColor = y->isBlack;
if (z->left == NIL) {
child = z->right;
transplant(z, z->right);
}
else if (z->right == NIL) {
child = z->left;
transplant(z, z->left);
}
else {
node* aux = z->right;
while (aux->left != NIL) aux = aux->left;
y = aux;
origColor = y->isBlack;
child = y->right;
if (y->dad == z) child->dad = y;
// otherwise
else {
transplant(y, y->right);
y->right = z->right;
y->right->dad = y;
}
transplant(z, y);
y->left = z->left;
y->left->dad = y;
y->isBlack = z->isBlack;
}
if (origColor == true) remove_fix_up(child);
}
void RBT::remove_fix_up(node* root) {
while (root != treeRoot && root->isBlack == true) {
if (root == root->dad->left) {
node* brother = root->dad->right;
if (brother->isBlack == false) {
brother->isBlack = true;
root->dad->isBlack = false;
leftRotate(root->dad);
brother = root->dad->right;
}
if (brother->left->isBlack == true && brother->right->isBlack == true) {
brother->isBlack = false;
root = root->dad;
}
else {
if (brother->right->isBlack == true) {
brother->left->isBlack = true;
brother->isBlack = false;
rightRotate(brother);
brother = root->dad->right;
}
brother->isBlack = root->dad->isBlack;
root->dad->isBlack = true;
brother->right->isBlack = true;
leftRotate(root->dad);
root = treeRoot;
}
}
else if (root == root->dad->right) {
node* brother = root->dad->left;
if (brother->isBlack == false) {
brother->isBlack = true;
root->dad->isBlack = false;
rightRotate(root->dad);
brother = root->dad->left;
}
if (brother->left->isBlack == true && brother->right->isBlack == true) {
brother->isBlack = false;
root = root->dad;
}
else {
if (brother->left->isBlack == true) {
brother->right->isBlack = true;
brother->isBlack = false;
leftRotate(brother);
brother = root->dad->left;
}
brother->isBlack = root->dad->isBlack;
root->dad->isBlack = true;
brother->left->isBlack = true;
rightRotate(root->dad);
root = treeRoot;
}
}
}
root->isBlack = true;
redoRoot();
}
//MAIN
int main() {
RBT arbore;
string cerinta;
while (cin >> cerinta) {
ll val = 0;
if (cerinta == "I" || cerinta == "C" || cerinta == "S") cin >> val;
if (cerinta[0] == 'I') {
arbore.insert(val);
}
else if (cerinta[0] == 'C') {
cout << arbore.inTree(val) << '\n';
}
else if (cerinta[0] == 'S') {
arbore.remove(val);
}
else if (cerinta.length() > 1 && cerinta[2] == 'X') {
// diferenta intre maxim si minim (succesorul lui 0, predecesorul lui INF)
ll minn = arbore.successor(0);
ll maxx = arbore.predecessor(INF + 5);
if (minn == -maxx) cout << "-1\n";
else if (minn == maxx) cout << "-1\n";
else cout << maxx - minn << '\n';
}
else if (cerinta.length() > 1 && cerinta[2] == 'N') {
// minim de diferenta intre x si succesorul lui
ll v1 = arbore.successor(0);
ll v2 = arbore.successor(v1 + 1);
//cout << v1 << ' ' << v2 << '\n';
if (v1 == v2) cout << "-1\n";
else if (v2 == INF) cout << "-1\n";
else cout << arbore.sorted(v1, INF - 1) << '\n';
}
}
return 0;
}