Pagini recente » Cod sursa (job #2661230) | Cod sursa (job #918055) | Cod sursa (job #627780) | Cod sursa (job #405332) | Cod sursa (job #2083106)
#include <bits/stdc++.h>
using namespace std;
const int BFACTOR = 5;
struct Node {
int size;
int keys[2 * BFACTOR];
Node *child[2 * BFACTOR];
Node(Node *nil = nullptr):
size(0) {
child[0] = nil;
}
};
void splitChild(Node *father, int index) {
Node *left = father->child[index];
Node *right = new Node(nullptr);
left->size = right->size = BFACTOR - 1;
for (int i = BFACTOR; i < 2 * BFACTOR - 1; ++i) {
right->keys[i - BFACTOR] = left->keys[i];
right->child[i - BFACTOR] = left->child[i];
}
right->child[BFACTOR - 1] = left->child[2 * BFACTOR - 1];
for (int i = father->size - 1; i >= index; --i)
father->keys[i + 1] = father->keys[i];
for (int i = father->size; i >= index + 1; --i)
father->child[i + 1] = father->child[i];
father->keys[index] = left->keys[BFACTOR - 1];
father->child[index] = left;
father->child[index + 1] = right;
++father->size;
if (left->child[0] == nullptr)
right->child[0] = nullptr;
}
void _insertValue(Node *curr, int value) {
int pos = 0;
while (pos < curr->size && value > curr->keys[pos])
++pos;
if (pos < curr->size && value == curr->keys[pos])
return;
if (curr->child[0] == nullptr) {
for (int i = curr->size; i >= pos; --i)
curr->keys[i + 1] = curr->keys[i];
curr->keys[pos] = value;
++curr->size;
return;
}
if (curr->child[pos]->size == 2 * BFACTOR - 1) {
splitChild(curr, pos);
if (value < curr->keys[pos])
_insertValue(curr->child[pos], value);
else
_insertValue(curr->child[pos + 1], value);
return;
}
_insertValue(curr->child[pos], value);
}
Node *insertValue(Node *root, int value) {
if (root->size == 2 * BFACTOR - 1) {
Node *newRoot = new Node(root);
splitChild(newRoot, 0);
_insertValue(newRoot, value);
return newRoot;
}
_insertValue(root, value);
return root;
}
int countValue(Node *curr, int value) {
int pos = 0;
while (pos < curr->size && value > curr->keys[pos])
++pos;
if (pos < curr->size && value == curr->keys[pos])
return true;
if (curr->child[0] == nullptr)
return false;
return countValue(curr->child[pos], value);
}
int lastLevel = -1;
int dfsCheck(Node *curr, int level) {
if (curr->child[0] == nullptr) {
if (lastLevel != -1 && lastLevel != level)
return 0;
lastLevel = level;
return 1;
}
int answer = 1;
for (int i = 0; i <= curr->size; ++i)
answer = min(answer, dfsCheck(curr->child[i], level + 1));
return answer;
}
void moveKeyLeft(Node *father, int index) {
Node *left = father->child[index - 1];
Node *right = father->child[index];
for (int i = right->size - 1; i >= 0; --i)
right->keys[i + 1] = right->keys[i];
for (int i = right->size; i >= 0; --i)
right->child[i + 1] = right->child[i];
right->keys[0] = father->keys[index - 1];
right->child[0] = left->child[left->size];
father->keys[index - 1] = left->keys[left->size - 1];
--left->size;
++right->size;
if (right->child[1] == nullptr)
right->child[0] = nullptr;
}
void moveKeyRight(Node *father, int index) {
Node *left = father->child[index];
Node *right = father->child[index + 1];
left->keys[left->size] = father->keys[index];
left->child[left->size + 1] = right->child[0];
father->keys[index] = right->keys[0];
for (int i = 0; i < right->size - 1; ++i)
right->keys[i] = right->keys[i + 1];
for (int i = 0; i < right->size; ++i)
right->child[i] = right->child[i + 1];
++left->size;
--right->size;
if (left->child[left->size] == nullptr)
right->child[0] = nullptr;
}
Node *lowerKey(Node *father, int index) {
Node *left = father->child[index];
Node *right = father->child[index + 1];
left->keys[left->size] = father->keys[index];
for (int i = 0; i < BFACTOR; ++i)
left->keys[left->size + i + 1] = right->keys[i];
for (int i = BFACTOR; i < 2 * BFACTOR; ++i)
left->child[i] = right->child[i - BFACTOR];
for (int i = index; i < father->size - 1; ++i)
father->keys[i] = father->keys[i + 1];
for (int i = index + 1; i < father->size; ++i)
father->child[i] = father->child[i + 1];
--father->size;
left->size = 2 * BFACTOR - 1;
delete right;
return left;
}
int treeMinimum(Node *curr) {
if (curr->child[0] == nullptr)
return curr->keys[0];
return treeMinimum(curr->child[0]);
}
int treeMaximum(Node *curr) {
if (curr->child[0] == nullptr)
return curr->keys[curr->size - 1];
return treeMaximum(curr->child[curr->size]);
}
void _deleteValue(Node *curr, int value) {
int pos = 0;
while (pos < curr->size && value > curr->keys[pos])
++pos;
if (pos < curr->size && value == curr->keys[pos]) {
if (curr->child[0] == nullptr) {
for (int i = pos; i < curr->size - 1; ++i)
curr->keys[i] = curr->keys[i + 1];
--curr->size;
return;
}
if (curr->child[pos]->size >= BFACTOR) {
curr->keys[pos] = treeMaximum(curr->child[pos]);
_deleteValue(curr->child[pos], curr->keys[pos]);
return;
}
if (curr->child[pos + 1]->size >= BFACTOR) {
curr->keys[pos] = treeMinimum(curr->child[pos + 1]);
_deleteValue(curr->child[pos + 1], curr->keys[pos]);
return;
}
Node *next = lowerKey(curr, pos);
_deleteValue(next, value);
} else if (curr->child[0] == nullptr)
return;
if (curr->child[pos]->size == BFACTOR - 1) {
if (pos - 1 >= 0 && curr->child[pos - 1]->size >= BFACTOR)
moveKeyLeft(curr, pos);
else if (pos + 1 <= curr->size && curr->child[pos + 1]->size >= BFACTOR)
moveKeyRight(curr, pos);
else {
if (pos + 1 <= curr->size) {
_deleteValue(lowerKey(curr, pos), value);
return;
} else {
_deleteValue(lowerKey(curr, pos - 1), value);
return;
}
}
}
_deleteValue(curr->child[pos], value);
}
Node *deleteValue(Node *root, int value) {
if (root->size == 1 && root->child[0]->size == BFACTOR - 1 && root->child[1]->size == BFACTOR - 1) {
Node *newRoot = lowerKey(root, 0);
_deleteValue(newRoot, value);
return newRoot;
}
_deleteValue(root, value);
return root;
}
int main() {
assert(freopen("hashuri.in", "r", stdin));
assert(freopen("hashuri.out", "w", stdout));
Node *root = new Node();
root->child[0] = nullptr;
int N;
scanf("%d", &N);
while (N--) {
int op, x;
scanf("%d %d", &op, &x);
if (op == 1)
root = insertValue(root, x);
else if (op == 2)
root = deleteValue(root, x);
else
cout << countValue(root, x) << '\n';
}
return 0;
}