#include <bits/stdc++.h>
using
namespace
std;
template
<
class
T1,
class
T2,
class
Comparator = less<T2>,
class
Hash = hash<T1> >
class
indexed_priority_queue {
unordered_map<T1,
long
long
int
, Hash> m;
vector<pair<T1, T2> > v;
long
long
numberOfElement;
Comparator comp;
long
long
capacity = LLONG_MAX;
long
long
int
getValueIndex(T1 key)
{
if
(m[key] == 0) {
cout <<
"No Such Key Exist"
;
return
-1;
}
return
v[m[key] - 1];
}
void
heapify(vector<pair<T1, T2> >& v,
long
long
int
heap_size,
long
long
index)
{
long
long
leftChild = 2 * index + 1,
rightChild = 2 * index + 2,
suitableNode = index;
if
(leftChild < heap_size
&& comp(v[suitableNode].second,
v[leftChild].second)) {
suitableNode = leftChild;
}
if
(rightChild < heap_size
&& comp(v[suitableNode].second,
v[rightChild].second)) {
suitableNode = rightChild;
}
if
(suitableNode != index) {
pair<T1, T2> temp = v[index];
v[index] = v[suitableNode];
v[suitableNode] = temp;
m[v[index].first] = index + 1;
m[v[suitableNode].first]
= suitableNode + 1;
heapify(v, numberOfElement,
suitableNode);
}
}
public
:
indexed_priority_queue()
{
numberOfElement = 0;
m.clear();
v.clear();
}
void
push(T1 key, T2 value)
{
if
(numberOfElement == capacity) {
cout <<
"Overflow"
;
return
;
}
if
(m[key] != 0) {
cout <<
"Element Already Exists"
;
return
;
}
v.push_back(make_pair(key, value));
numberOfElement++;
m[key] = numberOfElement;
long
long
index = numberOfElement - 1;
while
(index != 0
&& comp(v[(index - 1) / 2].second,
v[index].second)) {
pair<T1, T2> temp = v[index];
v[index] = v[(index - 1) / 2];
v[(index - 1) / 2] = temp;
m[v[index].first] = index + 1;
m[v[(index - 1) / 2].first]
= (index - 1) / 2 + 1;
index = (index - 1) / 2;
}
}
void
pop()
{
if
(numberOfElement == 0) {
cout <<
"UnderFlow"
;
return
;
}
v.erase(v.begin());
numberOfElement--;
heapify(v, numberOfElement, 0);
}
pair<T1, T2> top() {
return
v[0]; }
long
long
int
size() {
return
numberOfElement; }
bool
empty() {
return
numberOfElement == 0; }
void
changeAtKey(T1 key, T2 value)
{
if
(m[key] == 0) {
cout <<
"No Such Key Exist"
;
return
;
}
long
long
index = m[key] - 1;
v[index].second = value;
heapify(v, numberOfElement, index);
while
(index != 0
&& comp(v[(index - 1) / 2].second,
v[index].second)) {
pair<T1, T2> temp = v[index];
v[index] = v[(index - 1) / 2];
v[(index - 1) / 2] = temp;
m[v[index].first] = index + 1;
m[v[(index - 1) / 2].first]
= (index - 1) / 2 + 1;
index = (index - 1) / 2;
}
}
};
void
display(indexed_priority_queue<
int
,
int
> IPQ)
{
indexed_priority_queue<
int
,
int
> temp = IPQ;
while
(!IPQ.empty()) {
pair<
int
,
int
> tmp;
tmp = IPQ.top();
IPQ.pop();
cout <<
"( "
<< tmp.first <<
", "
<< tmp.second <<
" ) "
;
}
cout <<
'\n'
;
}
int
main()
{
indexed_priority_queue<
int
,
int
> IPQ;
cout <<
"Checking if initially the IPQ is empty\n"
;
if
(IPQ.empty())
cout <<
"IPQ is empty\n"
;
else
cout <<
"IPQ is not empty\n"
;
cout <<
"Inserting pairs (2, 1), (3, 7), "
<<
" (1, 0) and (4, 5)\n"
;
IPQ.push(2, 1);
IPQ.push(3, 7);
IPQ.push(1, 0);
IPQ.push(4, 5);
cout <<
"IPQ: "
;
display(IPQ);
cout <<
'\n'
;
cout <<
"Size: "
<< IPQ.size() << endl;
cout <<
"Top: "
<< IPQ.top().first
<<
", "
<< IPQ.top().second
<<
"\n\n"
;
cout <<
"Changing value associated with"
<<
" key 3 to 2 and 1 to 9\n"
;
IPQ.changeAtKey(3, 2);
IPQ.changeAtKey(1, 9);
cout <<
"Size: "
<< IPQ.size() << endl;
cout <<
"Top: "
<< IPQ.top().first
<<
", "
<< IPQ.top().second
<<
"\n\n"
;
cout <<
"Popping an element from IPQ: "
;
IPQ.pop();
cout <<
"\nPopping an element from IPQ: "
;
IPQ.pop();
cout <<
'\n\n'
;
cout <<
"IPQ: "
;
display(IPQ);
cout <<
'\n'
;
cout <<
"Size: "
<< IPQ.size() << endl;
cout <<
"Top: "
<< IPQ.top().first
<<
", "
<< IPQ.top().second
<<
"\n\n"
;
return
0;
}