#pragma once
#include<iostream>
#include<vector>
using namespace std;
namespace m
{
template<class T>
struct less
{
bool operator()(const T& A,const T& B)
{
return A < B;
}
};
template<class T>
struct greater
{
bool operator()(const T& A, const T& B)
{
return A > B;
}
};
template <class T, class Container = vector<T>, class Compare = less<T> >
class priority_queue
{
public:
priority_queue() = default;
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
{
while (first != last)
{
this->push(*first);
first++;
}
}
bool empty() const
{
return c.empty();
}
size_t size() const
{
return c.size();
}
T top() const
{
return c.front();
}
void push(const T& x)
{
c.push_back(x);
this->AdjustUP(c.size() - 1);
}
void pop()
{
if (empty())
return;
swap(c.front(),c.back());
c.pop_back();
AdjustDown(0);
}
private:
void AdjustUP(int child)
{
int parent = (child - 1) / 2;
while (child)
{
if (comp(c[parent], c[child]))
{
swap(c[parent], c[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
return;
}
}
}
void AdjustDown(int parent)
{
int child = 2 * parent;
while (child < size())
{
if (child < size() - 1 && comp(c[child], c[child + 1]))
{
child++;
}
if (comp(c[parent], c[child]))
{
swap(c[parent], c[child]);
parent = child;
child = 2 * parent;
}
else
return;
}
}
void swap(T& left, T& right)
{
T c = left;
left = right;
right = c;
}
Container c;
Compare comp;
};
};