Cod sursa(job #2906598)

Utilizator RaduAntoneoAntonio Alexandru Radu RaduAntoneo Data 26 mai 2022 19:04:30
Problema Heapuri cu reuniune Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4 kb
#include <bits/stdc++.h>
using namespace std;
 
ifstream f("mergeheap.in");
ofstream g("mergeheap.out");
#define cin f
#define cout g

struct node {
    int valoare, nr_copii;
    node *fiu_stanga, *frate_dreapta, *tata;
};

node* new_node(int val) {
    node* aux = new node;
    aux->valoare = val;
    aux->nr_copii = 0;
    aux->fiu_stanga = aux->frate_dreapta = aux->tata = NULL;
    return aux;
}
 
struct HeapBinomial {
    list<node*> Heap;
    list<node*>::iterator get_maxim() {
        list<node*>::iterator p, p_mx;
        int mx = -2147483640;
        for(p = Heap.begin(); p != Heap.end(); p++)
            if((*p)->valoare > mx) {
                mx = (*p)->valoare;
                p_mx = p;
            }
        return p_mx;
    }
 
    void delete_radacina(node* tree, HeapBinomial& heap) {
        if(tree->nr_copii == 0 ) {
            delete tree;
            return;
        }

        node* aux = tree;
        tree->fiu_stanga->tata = NULL;
        heap.Heap.push_front(tree->fiu_stanga);
        tree = tree->fiu_stanga;
        while(tree->frate_dreapta) {
            tree->frate_dreapta->tata = NULL;
            heap.Heap.push_front(tree->frate_dreapta);
            tree = tree->frate_dreapta;
        }
        delete aux;
    }
 
    void tree_union(node* t1, node* t2) {
        if(t1->valoare < t2->valoare)
            swap(*t1, *t2);
 
        t2->frate_dreapta = t1->fiu_stanga;
        t2->tata = t1;
        t1->fiu_stanga = t2;
        t1->nr_copii++;
    }
 
    void adjust() {
        if(Heap.size() <= 1) return;
        auto prev = Heap.begin();
        auto curr = prev;
        curr++;
        auto next = curr;
        next++;
 
        while(curr != Heap.end()) {
            while((next == Heap.end() || (*next)->nr_copii > (*curr)->nr_copii) && curr != Heap.end() && (*prev)->nr_copii == (*curr)->nr_copii) {
                tree_union(*curr, *prev);
                auto aux = prev;
                if(prev == Heap.begin()) {
                    prev++;
                    curr++;
                    if(next != Heap.end())
                        next++;
                }
                else prev--;
                Heap.erase(aux);
            }
 
            prev++;
            if(curr != Heap.end()) curr++;
            if(next != Heap.end()) next++;
        }
    }

    void push(int val) {
        node *tree = new_node(val);
        Heap.push_front(tree);
        adjust();
    }
 
    void heap_union(HeapBinomial& heap2) {
        auto p1 = Heap.begin();
        auto p2 = heap2.Heap.begin();
        list<node*> new_heap;
 
        while(p1 != Heap.end() && p2 != heap2.Heap.end()) {
            if((*p1)->nr_copii <= (*p2)->nr_copii) {
                new_heap.push_back(*p1);
                p1++;
            }
            else {
                new_heap.push_back(*p2);
                p2++;
            }
        }
        while(p1 != Heap.end()) {
            new_heap.push_back(*p1);
            p1++;
        }
        while(p2 != heap2.Heap.end()) {
            new_heap.push_back(*p2);
            p2++;
        }
        heap2.Heap.clear();
        Heap = new_heap;
        adjust();
    }
 
    void print_remove_max() {
        auto root = get_maxim();
        cout << (*root)->valoare << '\n';
        HeapBinomial new_heap;
        delete_radacina((*root), new_heap);
        Heap.erase(root);
        heap_union(new_heap);
    }
};
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    HeapBinomial Heap[101];
    cin >> n >> m;
    int nr, heap, x, h1, h2;
    for(int i = 1; i <= m; i++) {
        cin >> nr;
        if(nr == 1) {
            cin >> heap >> x;
            Heap[heap].push(x);
        }
        if(nr == 2) {
            cin >> heap;
            Heap[heap].print_remove_max();
        }
        if(nr == 3){
            cin >> h1 >> h2;
            Heap[h1].heap_union( Heap[h2] );
        }
    }
}