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;    
}
原文地址:https://www.cnblogs.com/staginner/p/2482020.html