Cod sursa(job #2595300)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 7 aprilie 2020 15:24:36
Problema Sortare prin comparare Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.02 kb
// 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("algsort.in");
ofstream fout("algsort.out");

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;
}