Pagini recente » Cod sursa (job #1774647) | Cod sursa (job #2196282) | Cod sursa (job #1805496) | Cod sursa (job #1043571) | Cod sursa (job #1070875)
#include <fstream>
using namespace std;
namespace e_024_heapuri
{
template <typename T, int MAX_N>
class heap
{
private:
T a[MAX_N];
int indexes[MAX_N]; //retrieves the original index of the position in heap
int positions[MAX_N]; //give the position in heap for each index
int N;
int parent(int i) { return (i - 1) / 2; }
inline int left_child(int i) { return 2 * i + 1; }
inline int right_child(int i) { return 2 * i + 2; }
public:
heap(): N(0) {}
~heap() {}
T operator () (int i)
{
return a[i];
}
void insert(T x, int index)
{
a[N] = x;
positions[index] = N;
indexes[N] = index;
N++;
update_position(N - 1);
}
void remove(int index)
{
//exchange with the last element
int pos = positions[index];
exchange_positions(pos, N - 1);
//remove one element
N--;
//update the heap
update_position(pos);
}
private:
/**
* Update the heap if the element at the given position has changed its value.
* Only upward updates are performed in the heap.
* The new value might not respect the heap structure. The other elements are in the heap format.
* Usefull after one element was inserted/deleted at the end of the vector.
*/
void update_position(int position)
{
int current_pos = position;
int parent_pos;
//upward updating
while (current_pos > 0 && a[current_pos] < a[parent_pos = parent(current_pos)]) {
//exchange the places in heap
exchange_positions(current_pos, parent_pos);
current_pos = parent_pos;
}
//downward updating
int next_pos;
//update only if upward updating wasn't performed
if (current_pos == position) {
while (current_pos >= 0)
{
next_pos = -1;
//check the children of the current node and their values
int pos_left_child = left_child(current_pos);
int pos_right_child = right_child(current_pos);
bool left_available = false, right_available = false;
if (pos_left_child < N && a[pos_left_child] < a[current_pos]) {
next_pos = pos_left_child; left_available = true;
}
if (pos_right_child < N && a[pos_right_child] < a[current_pos]) {
next_pos = pos_right_child;
right_available = true;
}
//if the node has two children choose the minimum child
if (left_available && right_available) {
if (a[pos_left_child] < a[pos_right_child]) next_pos = pos_left_child;
else next_pos = pos_right_child;
}
//if necessary, exchange the places in heap
if (next_pos >= 0) exchange_positions(current_pos, next_pos);
current_pos = next_pos;
}
}
}
inline void exchange_positions(int pos_i, int pos_j)
{
//exchange the values
T aux = a[pos_i];
a[pos_i] = a[pos_j];
a[pos_j] = aux;
//get the original indexes at the given positions
int index_i = indexes[pos_i];
int index_j = indexes[pos_j];
//exchange the positions
positions[index_i] = pos_j;
positions[index_j] = pos_i;
//exchange the indexes
indexes[pos_i] = index_j;
indexes[pos_j] = index_i;
}
};
}
//int e_024_heapuri()
int main()
{
string in_file = "heapuri.in";
string out_file = "heapuri.out";
int N;
const int MAX_N = 200000;
e_024_heapuri::heap<int, MAX_N> heap_;
ifstream ifs(in_file);
ofstream ofs(out_file);
ifs >> N;
int index = -1;
for (int i = 0; i < N; i++) {
int op;
ifs >> op;
if (op == 1) {
index++;
int x;
ifs >> x;
heap_.insert(x, index);
}
else if (op == 2) {
int index_to_remove;
ifs >> index_to_remove;
heap_.remove(index_to_remove - 1);
}
else { //op == 3
//write the minimum to file
ofs << heap_(0) << '\n';
}
}
ofs.close();
ifs.close();
return 0;
}