Cod sursa(job #1223330)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 27 august 2014 17:04:17
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.82 kb
#include <iostream>
#include <cassert>


class MinHeap
{
public:
    MinHeap(int capacity);
    ~MinHeap();

    void add(int value);
    void removeXth(int x);
    int getMin() const;

private:
    void swim(int k);
    void sink(int k);
    void delMin();

    int m_capacity;
    int m_totalInserts, m_currentElems;
    int *pq;
    int *elems;
    int *pos;
};

MinHeap::MinHeap(int capacity)
    : m_capacity(capacity),
      m_totalInserts(0),
      m_currentElems(0),
      pq(new int[m_capacity+1]),
      elems(new int[m_capacity+1]),
      pos(new int[m_capacity+1])
{
    // nothing to do
}

MinHeap::~MinHeap()
{
    delete pq;
    delete elems;
    delete pos;
}

void MinHeap::add(int value)
{
    elems[++m_totalInserts] = value;
    pq[++m_currentElems] = m_totalInserts;
    pos[m_totalInserts] = m_currentElems;
    swim(m_currentElems);
}


void MinHeap::removeXth(int x)
{
    // first make sure the xth element gets to the root of the heap.
    elems[x] = elems[pq[1]] - 1;
    swim(pos[x]);

    // then delete it by calling delMin().
    delMin();
}

void MinHeap::swim(int k)
{
    assert(k >= 1 && k <= m_currentElems);
    while (k > 1 && elems[pq[k]] < elems[pq[k/2]]) {
        pos[pq[k]] = k/2;
        pos[pq[k/2]] = k;
        std::swap(pq[k], pq[k/2]);
        k /= 2;
    }
}

void MinHeap::sink(int k)
{
    assert(k >= 1 && k < m_currentElems);
    while (2 * k <= m_currentElems) {
        int j = 2 * k;
        if (j < m_currentElems && elems[pq[j]] > elems[pq[j+1]])
            ++j;

        if (elems[pq[k]] < elems[pq[j]])
            break;

        pos[pq[k]] = j;
        pos[pq[j]] = k;
        std::swap(pq[k], pq[j]);
        k = j;
    }
}

void MinHeap::delMin()
{
    // map the deleted item to an invalid index in elems (pos does this - and 0
    // is an invalid index).
    pos[pq[1]] = 0;

    // replace the deleted item with the last one, which will be sinked
    // afterwards.
    pq[1] = pq[m_currentElems--];

    // map the pq[1] index of elems to the first position of pq. In fact,
    // pos[pq[x]] = x is an invariant.
    pos[pq[1]] = 1;

    // as previously mentioned, sink the element if the size of the heap is
    // bigger than 1.
    if (m_currentElems > 1)
        sink(1);
}

int MinHeap::getMin() const
{
    return elems[pq[1]];
}

int main()
{
    freopen("heapuri.in", "r", stdin);
    freopen("heapuri.out", "w", stdout);

    int N;
    scanf("%d", &N);
    MinHeap *heap = new MinHeap(N);

    for (; N; --N) {
        int code;
        scanf("%d", &code);

        if (code == 1) {
            int newElem;
            scanf("%d", &newElem);
            heap->add(newElem);
        } else if (code == 2) {
            int index;
            scanf("%d", &index);
            heap->removeXth(index);
        } else {
            printf("%d\n", heap->getMin());
        }
    }

    delete heap;
    return 0;
}