Pagini recente » Cod sursa (job #2774299) | Cod sursa (job #2179336) | Cod sursa (job #3227908) | Cod sursa (job #1908806) | Cod sursa (job #2595298)
// Splay Trees
// insert(x) => insert x into the tree if it is not already in the tree
// lower_bound(x) => return the pointer to the first value in the tree that does not compare less than x or nullptr if there is no such value
// find(x) => return pointer to the value of x in the tree or nullptr if x does not exist in the tree
// erase(x) => erase x from the tree if it is in the tree
// size() => returns how many elements are in the tree
#include <bits/stdc++.h>
using namespace std;
ifstream fin("input.txt");
ofstream fout("output.txt");
class SplayTree {
private:
struct node {
pair <int, int> value;
node *left, *right, *parent;
node(const pair <int, int> &vl = make_pair(0, 0), node* p = nullptr, node* l = nullptr, node* r = nullptr) : value(vl), parent(p), left(l), right(r) {}
};
node* root;
int tree_size;
// rotation on the edge A - left(A)
void left_rotate(node *A) {
node *B = A -> right;
if (A -> right) A -> right = B -> left;
if (B -> left) B -> left -> parent = A;
B -> parent = A -> parent;
if (A -> parent == nullptr) {
if (A == root)
root = B;
}
else if (A == A -> parent -> left)
A -> parent -> left = B;
else
A -> parent -> right = B;
B -> left = A;
A -> parent = B;
}
// rotation on the edge A - right(A)
void right_rotate(node *A) {
node *B = A -> left;
if (A -> left) A -> left = B -> right;
if (B -> right) B -> right -> parent = A;
B -> parent = A -> parent;
if (A -> parent == nullptr) {
if (A == root)
root = B;
}
else if (A == A -> parent -> left)
A -> parent -> left = B;
else
A -> parent -> right = B;
B -> right = A;
A -> parent = B;
}
void splay(node *x) {
if (!x) return;
while (x -> parent) {
if (x -> parent -> parent == nullptr) { // zig
if (x -> parent -> left == x) right_rotate(x -> parent);
else left_rotate(x -> parent);
}
else {
if (x -> parent -> left == x) {
if (x -> parent -> parent -> left == x -> parent) {
// zig-zig
right_rotate(x -> parent -> parent);
right_rotate(x -> parent);
}
else {
// zig-zag
right_rotate(x -> parent);
left_rotate(x -> parent);
}
}
else {
if (x -> parent -> parent -> right == x -> parent) {
// zig-zig
left_rotate(x -> parent -> parent);
left_rotate(x -> parent);
}
else {
// zig-zag
left_rotate(x -> parent);
right_rotate(x -> parent);
}
}
}
}
}
void replace(node* A, node* B) {
if (!A -> parent)
root = B;
else if (A == A -> parent -> left)
A -> parent -> left = B;
else
A -> parent -> right = B;
if (B) B -> parent = A -> parent;
}
node* get_max_node(node *x) const {
if (!x) return nullptr;
node *current_node = x;
while (current_node -> right)
current_node = current_node -> right;
return current_node;
}
node* get_min_node(node* x) const {
if (!x) return nullptr;
node *current_node = x;
while (current_node -> left)
current_node = current_node -> left;
return current_node;
}
public:
SplayTree(node* r = nullptr, int sz = 0) : root(r), tree_size(sz) {}
node* lower_bound(const int &x) const {
node *current_node = root, *last_node = nullptr;
while (current_node) {
if (x == current_node -> value.first) return current_node; // found
if (x < current_node -> value.first){
last_node = current_node;
current_node = current_node -> left;
}
else
current_node = current_node -> right;
}
return last_node;
}
node* find(const int &x) const {
node *temp = lower_bound(x);
if (!temp or temp -> value.first != x) return nullptr;
return temp;
}
void insert(const int &x) {
node *current_node = root, *last_node = nullptr;
while (current_node) {
last_node = current_node;
if (x == current_node -> value.first) {
++current_node -> value.second;
return; // already in the tree
}
if (x < current_node -> value.first)
current_node = current_node -> left;
else
current_node = current_node -> right;
}
current_node = new node(make_pair(x, 1), last_node);
if (!last_node) root = current_node;
else if (x < last_node -> value.first) last_node -> left = current_node;
else last_node -> right = current_node;
splay(current_node);
++tree_size;
}
void erase(const int &x) {
node *current_node = find(x);
if (!current_node) return; // not in the tree
--tree_size;
splay(current_node);
if (!current_node -> left)
replace(current_node, current_node -> right);
else if (!current_node -> right)
replace(current_node, current_node -> left);
else {
node *minn = get_min_node(current_node -> right);
if (minn -> parent != current_node) {
replace(minn, minn -> right);
minn -> right = current_node -> right;
minn -> right -> parent = minn;
}
replace(current_node, minn);
minn -> left = current_node -> left;
minn -> left -> parent = minn;
}
delete current_node;
}
inline int size() const {
return tree_size;
}
inline node* get_max() {
return get_max_node(root);
}
inline node* get_min() {
return get_min_node(root);
}
};
int main() {
// while (no_queries--) {
// string op; fin >> op;
// int val; fin >> val;
// if (op == "insert")
// T.insert(val);
// else if (op == "find")
// fout << (T.find(val) ? "Found\n" : "Not found\n");
// else
// T.erase(val);
// }
int n; fin >> n;
SplayTree T;
for (int x, i = 1; i <= n; ++i) {
fin >> x; T.insert(x);
}
for (int i = 1; i <= n; ++i) {
auto it = T.get_min();
if (it) {
while (it -> value.second--)
fout << it -> value.first << ' ';
T.erase(it -> value.first);
}
}
return 0;
}