URAL 1037 Memory Management

    为了查找标号最小的可用的block可以用一个以block标号为关键字的最小堆实现,同时为了能够修改正在使用的block延续的时间以及适时free过时的block,可以另外开一个以block开始使用的时刻为关键字的最小堆。

#include<stdio.h>

#include<string.h>

#define MAXD 30010

#define INF 0x3f3f3f3f

const int N = 30000, T = 600;

int now, M, u[4 * MAXD], t[4 * MAXD], last[2 * MAXD];

char b[5];

void build()

{

    int i, j, k;

    for(M = 1; M < N + 2; M <<= 1);

    memset(u, 0x3f, sizeof(u));

    memset(last, 0x3f, sizeof(last));

    memset(t, 0, sizeof(t));

    for(i = 1; i <= N; i ++)

        u[i + M] = i;

    for(i = M - 1; i >= 0; i --)

        u[i] = u[i << 1] < u[(i << 1) | 1] ? u[i << 1] : u[(i << 1) | 1];

}

void ufresh(int i)

{

    for(; i ^ 1; i >>= 1)

        u[i >> 1] = u[i] < u[i ^ 1] ? u[i] : u[i ^ 1];

}

void tfresh(int i)

{

    for(; i ^ 1; i >>= 1)

        t[i >> 1] = last[t[i]] < last[t[i ^ 1]] ? t[i] : t[i ^ 1];

}

void Delete()

{

    int k;

    while((k = t[1]) && now - last[t[1]] >= T)

    {

        t[k + M] = 0, tfresh(k + M);

        u[k + M] = k, ufresh(k + M);

    }

}

void solve()

{

    int k;

    scanf("%s", b);

    Delete();

    if(b[0] == '+')

    {

        k = u[1];

        printf("%d\n", k);

        u[k + M] = INF, ufresh(k + M);

        last[k] = now, t[k + M] = k, tfresh(k + M);

    }

    else

    {

        scanf("%d", &k);

        if(t[k + M] == 0)

            printf("-\n");

        else

        {

            printf("+\n");

            last[k] = now, tfresh(k + M);    

        }

    }

}

int main()

{

    build();

    while(scanf("%d", &now) == 1)

    {

        solve();    

    }

    return 0;    

}

 

你可能感兴趣的:(memory)