Cod sursa(job #770430)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 22 iulie 2012 23:56:02
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.73 kb

#include <fstream>

struct heap_data
{
    unsigned int value;
    unsigned int order_index;
};

inline void operator ^= (struct heap_data &first, struct heap_data &second)
{
    first.value ^= second.value;
    first.order_index ^= second.order_index;
}

inline void heap_up (struct heap_data *heap, unsigned int *order, unsigned int index)
{
    if (index)
    {
        const unsigned int VALUE(heap[index].value), FIRST_ORDER_INDEX(heap[index].order_index);
        unsigned int father((index - 1) >> 1), second_order_index;
        while (VALUE < heap[father].value)
        {
            heap[index].value = heap[father].value;
            second_order_index = heap[father].order_index;
            order[FIRST_ORDER_INDEX] ^= order[second_order_index];
            order[second_order_index] ^= order[FIRST_ORDER_INDEX];
            order[FIRST_ORDER_INDEX] ^= order[second_order_index];
            heap[index].order_index ^= heap[father].order_index;
            heap[father].order_index ^= heap[index].order_index;
            heap[index].order_index ^= heap[father].order_index;
            index = father;
            if (father)
            {
                --father;
                father >>= 1;
            }
            else
                break;
        }
        heap[index].value = VALUE;
    }
}

inline void heap_down (struct heap_data *heap, unsigned int heap_size, unsigned int *order, unsigned int index)
{
    unsigned int left((index << 1) + 1), right(left + 1), smallest;
    while (true)
    {
        if (left < heap_size && heap[left].value < heap[index].value)
            smallest = left;
        else
            smallest = index;
        if (right < heap_size && heap[right].value < heap[smallest].value)
            smallest = right;
        if (smallest == index)
            break;
        order[heap[index].order_index] ^= order[heap[smallest].order_index];
        order[heap[smallest].order_index] ^= order[heap[index].order_index];
        order[heap[index].order_index] ^= order[heap[smallest].order_index];
        heap[index] ^= heap[smallest];
        heap[smallest] ^= heap[index];
        heap[index] ^= heap[smallest];
        index = smallest;
        left = (index << 1) + 1;
        right = left + 1;
    }
}

int main (void)
{
    std::ifstream input("heapuri.in");
    unsigned int n;
    input >> n;
    char operation;
    unsigned int number;
    struct heap_data *heap(new struct heap_data [n]);
    unsigned int heap_size(0);
    unsigned int *order(new unsigned int [n]);
    unsigned int order_counter(0);
    std::ofstream output("heapuri.out");
    do
    {
        input >> operation;
        if (operation == '3')
            output << heap->value << '\n';
        else
        {
            input >> number;
            if (operation == '2')
            {
                --number;
                number = order[number];
                --heap_size;
                order[heap[heap_size].order_index] = order[heap[number].order_index];
                heap[number].value = heap[heap_size].value;
                heap[number].order_index = heap[heap_size].order_index;
                if (number > 0 && heap[number].value < heap[(number - 1) >> 1].value)
                    heap_up(heap,order,number);
                else
                    heap_down(heap,heap_size,order,number);
            }
            else
            {
                heap[heap_size].value = number;
                heap[heap_size].order_index = order_counter;
                order[order_counter] = heap_size;
                heap_up(heap,order,heap_size);
                ++heap_size;
                ++order_counter;
            }
        }
        --n;
    }
    while (n);
    delete [ ] heap;
    delete [ ] order;
    input.close();
    output.close();
    return 0;
}