Cod sursa(job #3294152)

Utilizator _Fibonacci_Caitaz _Fibonacci_ Data 17 aprilie 2025 08:54:56
Problema Heapuri Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 3.35 kb
#include <stdio.h>
#include <stdlib.h>

#define MAXN 200005

typedef struct {
    int prior; // valoarea elementului
    int id;    // ID unic (indexul cronologic de inserare)
} ItemType;

typedef struct heap {
    long maxHeapSize;
    long size;
    ItemType *elem;
} PriQueue, *APriQueue;

int idToPos[MAXN]; // id → poziția curentă în heap
int currentId = 0; // ID unic pentru fiecare inserare

// Funcții auxiliare
int getLeftChild(int i) { return 2 * i + 1; }
int getRightChild(int i) { return 2 * i + 2; }
int getParent(int i) { return (i - 1) / 2; }

// Swap și actualizare idToPos
void swap(ItemType *a, ItemType *b) {
    ItemType tmp = *a;
    *a = *b;
    *b = tmp;
}

// Min-heap siftUp
void siftUp(APriQueue h, int idx) {
    while (idx > 0 && h->elem[getParent(idx)].prior > h->elem[idx].prior) {
        int parent = getParent(idx);

        // actualizează maparea
        idToPos[h->elem[idx].id] = parent;
        idToPos[h->elem[parent].id] = idx;

        swap(&h->elem[idx], &h->elem[parent]);
        idx = parent;
    }
}

// Min-heap siftDown
void siftDown(APriQueue h, int idx) {
    int smallest = idx;
    while (1) {
        int left = getLeftChild(idx);
        int right = getRightChild(idx);

        if (left < h->size && h->elem[left].prior < h->elem[smallest].prior)
            smallest = left;
        if (right < h->size && h->elem[right].prior < h->elem[smallest].prior)
            smallest = right;

        if (smallest != idx) {
            idToPos[h->elem[idx].id] = smallest;
            idToPos[h->elem[smallest].id] = idx;
            swap(&h->elem[idx], &h->elem[smallest]);
            idx = smallest;
        } else {
            break;
        }
    }
}

PriQueue* makeQueue(int maxHeapSize) {
    PriQueue* q = (PriQueue*)malloc(sizeof(PriQueue));
    q->maxHeapSize = maxHeapSize;
    q->size = 0;
    q->elem = (ItemType*)malloc(maxHeapSize * sizeof(ItemType));
    return q;
}

void insert(PriQueue *h, ItemType x) {
    if (h->size >= h->maxHeapSize) {
        h->maxHeapSize *= 2;
        h->elem = realloc(h->elem, h->maxHeapSize * sizeof(ItemType));
    }
    h->elem[h->size] = x;
    idToPos[x.id] = h->size;
    siftUp(h, h->size);
    h->size++;
}

void erase(APriQueue h, int id) {
    int pos = idToPos[id];
    if (pos >= h->size) return;

    // înlocuiește cu ultimul element
    h->elem[pos] = h->elem[h->size - 1];
    idToPos[h->elem[pos].id] = pos;
    h->size--;

    // reechilibrare
    siftUp(h, pos);
    siftDown(h, pos);
}

ItemType getMin(APriQueue h) {
    return h->elem[0];
}

void freeQueue(APriQueue h) {
    if (h) {
        free(h->elem);
        free(h);
    }
}


int main() {
    FILE *fin = fopen("heapuri.in", "r");
    FILE *fout = fopen("heapuri.out", "w");

    int N;
    fscanf(fin, "%d", &N);

    PriQueue* heap = makeQueue(4);

    for (int i = 0; i < N; i++) {
        int op;
        fscanf(fin, "%d", &op);

        if (op == 1) {
            int x;
            fscanf(fin, "%d", &x);
            ItemType item;
            item.prior = x;
            item.id = ++currentId;
            insert(heap, item);
        } else if (op == 2) {
            int idToDelete;
            fscanf(fin, "%d", &idToDelete);
            erase(heap, idToDelete);
        } else if (op == 3) {
            fprintf(fout, "%d\n", getMin(heap).prior);
        }
    }

    freeQueue(heap);
    fclose(fin);
    fclose(fout);
    return 0;
}