Cod sursa(job #2371037)

Utilizator AplayLazar Laurentiu Aplay Data 6 martie 2019 15:16:48
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.32 kb
#include <cstdio>
#include <vector>
#include <set>

#define ADD 1
#define DELETE 2
#define MIN 3

#define N_MAX 200001

using namespace std;

int N, operation, value, position, valuesSize = 0, heapPosition[N_MAX], heapSize = 0;
pair<int, int> heap[N_MAX];

inline int father(int position) {
    return (1 + position) / 2 - 1;
}

inline int leftSon(int position) {
    return 2 * position + 1;
}

inline int rightSon(int position) {
    return 2 * position + 2;
}

void moveUp(pair<int, int>* heap, int& heapSize, int target, int* heapPosition) {
    while (0 < target) {
        int fatherPosition = father(target);
        if (heap[fatherPosition].first < heap[target].first) {
            break;
        }
        swap(heap[target], heap[fatherPosition]);
        swap(heapPosition[heap[target].second], heapPosition[heap[fatherPosition].second]);
        target = fatherPosition;
    }
}

void moveDown(pair<int, int>* heap, int& heapSize, int target, int* heapPosition) {
    while (leftSon(target) < heapSize) {
        int swapPosition = -1;
        int leftSonPosition = leftSon(target);
        if (heap[leftSonPosition].first < heap[target].first) {
            swapPosition = leftSonPosition;
        }
        int rightSonPosition = rightSon(target);
        if (rightSonPosition < heapSize 
                && heap[rightSonPosition].first < heap[leftSonPosition].first 
                && heap[rightSonPosition].first < heap[target].first) {
            swapPosition = rightSonPosition;
        }

        if (-1 != swapPosition) {
            swap(heap[target], heap[swapPosition]);
            swap(heapPosition[heap[target].second], heapPosition[heap[swapPosition].second]);
            target = swapPosition;
            continue;
        }

        break;
    }
}

void heapInsert(pair<int, int>* heap, int& heapSize, int value, int position, int* heapPosition) {
    heap[heapSize].first = value;
    heap[heapSize].second = position;
    heapPosition[position] = heapSize++;
    moveUp(heap, heapSize, heapSize - 1, heapPosition);
}

void heapDelete(pair<int, int>* heap, int& heapSize, int target, int* heapPosition) {
    --heapSize;
    swap(heap[target], heap[heapSize]);
    swap(heapPosition[heap[target].second], heapPosition[heap[heapSize].second]);
    if (0 < heapSize && heap[target].first < heap[father(target)].first) {
        moveUp(heap, heapSize, target, heapPosition);
    } else {
        moveDown(heap, heapSize, target, heapPosition);
    }
}

void printHeap() {
    printf("> ");
    for (int it = 0; it < heapSize; ++it) {
        printf("%d ", heap[it].first);
    }
    printf("\n");
}

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

    scanf("%d", &N);
    while (N--) {
        scanf("%d", &operation);
        switch (operation) {
            case ADD: {
                scanf("%d", &value);
                heapInsert(heap, heapSize, value, valuesSize++, heapPosition);
                // printHeap();
                break;
            }
            case DELETE: {
                scanf("%d", &position);
                heapDelete(heap, heapSize, heapPosition[position - 1], heapPosition);
                // printHeap();
                break;
            }
            case MIN: {
                printf("%d\n", heap[0].first);
                break;
            }
        }
    }

    return 0;
}