Pagini recente » Cod sursa (job #2297917) | Cod sursa (job #881327) | Cod sursa (job #1831335) | Cod sursa (job #567224) | Cod sursa (job #322504)
Cod sursa(job #322504)
/*
Author's name: Alin Tomescu
Website: http://alinush.isgreat.org
Date: 10:57 PM Monday, June 08, 2009
*/
#include <iostream>
#include <fstream>
using namespace std;
typedef unsigned long ulong;
const ulong MAX_OPERATIONS = 200000+1;
class SpecialHeap
{
public:
SpecialHeap()
: heapSize(0), indexCounter(0)
{}
public:
// Pushes a new number on the heap
void push(ulong number);
// Pops the number with that index off the heap
void pop(ulong id);
// Returns the min. number in the heap
ulong peek() const;
private:
// Internal heap array related operations
ulong getParent (ulong index) const { return (index-1)/2; }
ulong getLeftChild (ulong index) const { return 2*index+1; }
ulong getRightChild (ulong index) const { return 2*index+2; }
bool hasLeftChild (ulong index) const { return 2*index+1 < heapSize; }
bool hasRightChild (ulong index) const { return 2*index+2 < heapSize; }
bool hasChildren (ulong index) const { return hasLeftChild(index); }
bool isRoot (ulong index) const { return index == 0; }
bool hasParent (ulong index) const { return !isRoot(index); }
private:
ulong value(ulong id) const { return idToNumber[id]; }
bool areMappingsValid() const;
private:
// Each number is going to have an index or key or whatever you want to call it.
// The value of a number's index is the time (expressed as a number) when that
// number was inserted into the heap.
// Example:
// The index for the firstly inserted item is 0
// The index for the secondly inserted item is 1
// And so on, the index for the n'th inserted item is n-1
// Maps an index to a number. This is where the actual numbers are stored.
ulong idToNumber[MAX_OPERATIONS];
// Maps an index to its position in the internal heap array.
// (We need this for fast lookup when removing from the heap)
ulong idToHeapPos[MAX_OPERATIONS];
// Keeps a min-heap of the numbers but instead of storing the values it stores their indices
ulong heapOfIds[MAX_OPERATIONS];
ulong heapSize; // The current number of elements in the heap
ulong indexCounter; // The current index counter (this goes from 0 to inf)
};
ulong SpecialHeap::peek() const
{
return idToNumber[heapOfIds[0]];
}
void SpecialHeap::push(ulong number)
{
// Store the number in the id-to-number map
ulong id = indexCounter++;
idToNumber[id] = number;
// Now we need to actually put that number's id in the heap
// So we start by putting it at the "end" of the heap-array
ulong heapIndex = heapSize++;
heapOfIds[heapIndex] = id;
idToHeapPos[id] = heapIndex;
// And then we sift it up...
// But each time we swap an element while sifting we need to update
// our 'idToHeapPos' array with the new mapping
while(hasParent(heapIndex))
{
ulong parentHeapIndex = getParent(heapIndex);
ulong parentId = heapOfIds[parentHeapIndex];
if(value(id) < value(parentId))
{
// Swap the two...
std::swap(heapOfIds[heapIndex], heapOfIds[parentHeapIndex]);
std::swap(idToHeapPos[id], idToHeapPos[parentId]);
heapIndex = parentHeapIndex;
}
else
{
break;
}
}
}
void SpecialHeap::pop(ulong deletedId)
{
ulong lastId = heapOfIds[heapSize-1];
ulong heapIndex = idToHeapPos[deletedId];
// Replace the deleted element with the last one in the heap
heapOfIds[heapIndex] = lastId;
heapSize--;
// Update the id-to-heap-pos mapping
idToHeapPos[lastId] = heapIndex;
while(hasChildren(heapIndex))
{
// If one of the element's children is smaller
// than the element, then we need to swap the two
// Get the minimum child.
// We know there's a left child
// since that's the precondition for the loop.
ulong childHeapIndex = getLeftChild(heapIndex);
ulong childId = heapOfIds[childHeapIndex];
if(hasRightChild(heapIndex))
{
// Compare the two and store the minimum one...
ulong rightChildHeapIndex = getRightChild(heapIndex);
ulong rightChildId = heapOfIds[rightChildHeapIndex];
if(value(rightChildId) < value(childId))
{
childHeapIndex = rightChildHeapIndex;
childId = rightChildId;
}
}
if(value(childId) < value(lastId))
{
// Swap with the minimum
std::swap(heapOfIds[heapIndex], heapOfIds[childHeapIndex]);
std::swap(idToHeapPos[lastId], idToHeapPos[childId]);
heapIndex = childHeapIndex;
}
else
{
break;
}
}
}
int main()
{
const char * inFile = "heapuri.in";
const char * outFile = "heapuri.out";
ulong nOperations;
ifstream fin(inFile);
ofstream fout(outFile);
fin >> nOperations;
// Our "special" heap suited for this task
SpecialHeap * heap = new SpecialHeap;
for(ulong i = 0; i < nOperations; i++)
{
ulong op;
ulong number = -1;
fin >> op;
switch(op)
{
case 1:
{
fin >> number;
heap->push(number);
break;
}
case 2:
{
fin >> number;
// Our id mapping is off by one for convenience...
heap->pop(number-1);
break;
}
case 3:
{
fout << heap->peek() << "\n";
break;
}
}
}
fout.close();
fin.close();
return 0;
}