Cod sursa(job #2266968)

Utilizator 24601Dan Ban 24601 Data 22 octombrie 2018 23:48:30
Problema Heapuri Scor 40
Compilator c-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define SIZE 2000000
#define CH_SIZE 12
#define CHUNK (1 << 24)

struct ch_elem {
    int x;
    char ch[CH_SIZE];
};

struct elem {
    struct ch_elem x;
    int ins_time;
};

static int time_n, hlen;
static struct elem h[SIZE];
static int pos[SIZE];
static char buf[CHUNK], obuf[CHUNK];
static char hbuf[CH_SIZE];
static ssize_t blen, bpos = CHUNK, obpos;

static inline void h_bubble_up(int idx, struct elem v)
{
	struct elem pval;
	int pidx;

	while (idx > 0) {
	    pidx = idx >> 1;

		pval = h[pidx];
		if (pval.x.x < v.x.x)
			return;
		h[pidx] = v;
		pos[h[pidx].ins_time] = pidx;
		h[idx] = pval;
		pos[h[idx].ins_time] = idx;
		idx = pidx;
	}
}

static void h_bubble_down(int idx, struct elem v)
{
    struct elem c;
    int i1, i2;

    while (idx << 1 < hlen) {
        i1 = i2 = idx << 1;
        i2++;

        if (i2 < hlen && h[i2].x.x <= h[i1].x.x && h[i2].x.x < v.x.x) {
            c = h[i2];

            h[i2] = v;
            pos[h[i2].ins_time] = i2;

            h[idx] = c;
            pos[h[idx].ins_time] = idx;

            idx = i2;
        } else if (i1 < hlen && h[i1].x.x <= h[i2].x.x && h[i1].x.x < v.x.x) {
            c = h[i1];

            h[i1] = v;
            pos[h[i1].ins_time] = i1;

            h[idx] = c;
            pos[h[idx].ins_time] = idx;

            idx = i1;
        } else {
            break;
        }
    }
}

static void ins(int val)
{
	pos[++time_n] = hlen;
	h[hlen].ins_time = time_n;
	h[hlen].x.x = val;
	memcpy(h[hlen].x.ch, hbuf, CH_SIZE);
	h_bubble_up(hlen, h[hlen]);

	hlen++;
}

static void rm(int ins_time)
{
	h[pos[ins_time]] = h[hlen - 1];
    pos[h[hlen - 1].ins_time] = pos[ins_time];

	h_bubble_down(pos[ins_time], h[pos[ins_time]]);

	hlen--;
	if (hlen == 0) {
		return;
	}
}

static inline int read_int(void)
{
    int x = 0, hblen = 0;

    while (1) {
        if (bpos == CHUNK) {
            blen = read(0, buf, CHUNK);
            bpos = 0;
        }

        if ('0' <= buf[bpos] && buf[bpos] <= '9') {
            hbuf[hblen++] = buf[bpos];
            x = x * 10 + (buf[bpos] - '0');
        } else if (buf[bpos] == '\n') {
            hbuf[hblen++] = buf[bpos];
            hbuf[hblen] = '\0';
            bpos++;
            return x;
        }

        bpos++;
    }
}

static inline void write_int(void)
{
    int i;

    if (obpos > CHUNK - 5) {
        write(1, obuf, CHUNK);
        obpos = 0;
    }

    for (i = 0; h[0].x.ch[i] != '\0'; i++) {
        obuf[obpos++] = h[0].x.ch[i];
    }
}

int main(void)
{
    int ch, n = 0;

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

    n = read_int();

    while (n--) {
        if (bpos == CHUNK) {
            blen = read(0, buf, CHUNK);
            bpos = 0;
        }
        ch = buf[bpos++];

        if (bpos == CHUNK) {
            blen = read(0, buf, CHUNK);
            bpos = 0;
        }
        bpos++;

        if (ch == '1') {
            ins(read_int());
        } else if (ch == '2') {
            rm(read_int());
        } else {
            write_int();
        }
    }

    write(1, obuf, obpos);

    return 0;
}