Cod sursa(job #2595495)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 7 aprilie 2020 20:15:56
Problema Sortare prin comparare Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("algsort.in");
ofstream fout("algsort.out");

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution <int> _random(0, INT_MAX);

class Treap {
private:
    struct node {
        int key, priority;
        node *left, *right;
        node (const int &k = 0, node* l = nullptr, node* r = nullptr) : key(k), priority(_random(rnd)), left(l), right(r) {}
        ~node() {
            if (left) delete left;
            if (right) delete right;
        }
    };
    node *root;

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

    pair <node*, node*> split(node* A, const int &x) {
        if (!A) return make_pair(nullptr, nullptr);

        pair <node*, node*> temp;
        if (x >= A -> key) {
            temp = split(A -> right, x);
            A -> right = temp.first;
            return make_pair(A, temp.second);
        }   
        else {
            temp = split(A -> left, x);
            A -> left = temp.second;
            return make_pair(temp.first, A);
        }
    }

    node* join(node* A, node* B) {
        if (!A) return B;
        if (!B) return A;

        if (A -> priority > B -> priority) {
            A -> right = join(A -> right, B);
            return A;
        }
        else {
            B -> left = join(A, B -> left);
            return B;
        }
    }

    void DFS(node* n) {
        if (!n) return;
        DFS(n -> left);
        fout << n -> key << ' ';
        DFS(n -> right);
    }

public:
    Treap(node* r = nullptr) : root(r) {}

    void insert(const int &x) {
        pair <node*, node*> temp = split(root, x);
        node* new_node = new node(x);
        root = join(temp.first, join(new_node, temp.second));
    }

    void erase(const int &x) {
        pair <node*, node*> temp = split(root, x);
        pair <node*, node*> _temp = split(temp.first, x - 1);
        root = join(_temp.first, temp.second);
    }

    node* lower_bound(const int &x) const {
        node *current_node = root, *last_node = nullptr;
        while (current_node) {
            if (x == current_node -> key) return current_node;
            if (x < current_node -> key){
                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 -> key != x) return nullptr;
        return temp;
    }

    inline node* get_max() {
        return get_max_node(root);
    }

    inline node* get_min() {
        return get_min_node(root);
    }

    void Inorder() {
        DFS(root);
    }
};

int main() {
    int n; fin >> n;
    Treap T;

    for (int x, i = 1; i <= n; ++i) 
        fin >> x, T.insert(x);

    T.Inorder();

    return 0;
}