Cod sursa(job #3297207)

Utilizator stefanchpStefan Chiper stefanchp Data 22 mai 2025 03:29:41
Problema Heapuri cu reuniune Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.79 kb
#include <iostream>
#include <vector>
#include <fstream>

class binary_heap{
    private:
        std::vector<int> heap;

        inline int parent(int nod);
        inline int lefts(int nod);
        inline int rights(int nod);

        void sift(int pos);
        void percolate(int pos);
    
    public:
        binary_heap() {heap.push_back(0);}
        
        inline int getmax();
        void insert(int val);
        void replace(int val, int pos);
        void heapify(std::vector <int>& h);
        void eliminate(int pos);
        void merge(binary_heap& other);
        
        friend std::ostream& operator<<(std::ostream& out, const binary_heap &h)
        {
            for (int i = 1; i < h.heap.size(); i++)
                out << h.heap[i] << " ";
            return out;
        }
};

inline int binary_heap::parent(int nod)
{
    return nod >> 1;
}

inline int binary_heap::lefts(int nod)
{
    return nod << 1;
}

inline int binary_heap::rights(int nod)
{
    return (nod << 1) + 1;
}

inline int binary_heap::getmax()
{
    int val = heap[1];
    eliminate(1);
    return val;
}

void binary_heap::sift(int pos)
{
    if (pos < 1 || pos >= heap.size())
        return;
    int son, size_ = heap.size() - 1;
    if (size_ <= 0)
        return;
    while(true)
    {
        int left = lefts(pos);
        int right = rights(pos);
        int m = pos;
        if (left <= size_ && heap[left] > heap[m])
            m = left;
        if (right <= size_ && heap[right] > heap[m])
            m = right;
        
        if (m != pos)
        {
            std::swap(heap[pos], heap[m]);
            pos = m;
        }
        else
        {
            break;
        }
    }
}

void binary_heap::percolate(int pos)
{  
    int val = heap[pos];
    int parent_ = parent(pos);
    while(pos > 1 && val > heap[parent_])
    {
        heap[pos] = heap[parent_];
        pos = parent_;
        parent_ = parent(pos);
    }
    heap[pos] = val;
}

void binary_heap::insert(int val)
{
    heap.emplace_back(val);
    percolate(heap.size() - 1);
}

void binary_heap::replace(int val, int pos)
{
    int curent = heap[pos];
    heap[pos] = val;

    if (val > curent)
        percolate(pos);
    else if(val < curent)
        sift(pos);
}

void binary_heap::heapify(std::vector<int>& h)
{
    heap = h;
    for(int i = (heap.size() - 1) / 2; i >= 1; i--)
        sift(i);
}

void binary_heap::eliminate(int pos)
{
    if (pos < 1 || pos >= heap.size() || heap.size() <= 1) 
        return;
    heap[pos] = heap[heap.size() - 1];
    heap.pop_back();
    int parent_ = parent(pos);
    if (pos > 1 && heap[pos] > heap[parent_])
        percolate(pos);
    else
        sift(pos);
}

void binary_heap::merge(binary_heap& other)
{
    for (int i = 1; i < other.heap.size(); i++)
        insert(other.heap[i]);
    other.heap.clear();
    other.heap.emplace_back(0);
}

int main()
{
    std::ifstream fin("mergeheap.in");
    std::ofstream fout("mergeheap.out");
    std::ios_base::sync_with_stdio(false);
    fin.tie(NULL);
    int n, q, task, m, x;
    fin >> n >> q;
    binary_heap h[n + 1];
    for(int i = 1; i <= q; i++)
    {
        fin >> task;
        if(task == 1)
        {
            fin >> m >> x;
            h[m].insert(x);
        }
        else if(task == 2)
        {
            fin >> m;
            fout << h[m].getmax() << '\n';
        }
        else if(task == 3)
        {
            int m1, m2;
            fin >> m1 >> m2;
            h[m1].merge(h[m2]);
        }
        ///std::cout << "querry: " << i << '\n';
        ///for(int j = 1; j <= n; j++)
        ///std::cout<< j << ": " << h[j] << '\n';
    }
    fin.close();
    fout.close();
    return 0;
}