Pagini recente » Cod sursa (job #3300167) | Cod sursa (job #3168721) | Cod sursa (job #3249551) | Cod sursa (job #2503169) | Cod sursa (job #3297210)
#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;
}