Memory Control HDU - 2871(线段树区间合并)

Memory units are numbered from 1 up to N.
A sequence of memory units is called a memory block.
The memory control system we consider now has four kinds of operations:

  1. Reset Reset all memory units free.
  2. New x Allocate a memory block consisted of x continuous free memory units with the least start number
  3. Free x Release the memory block which includes unit x
  4. Get x Return the start number of the xth memory block(Note that we count the memory blocks allocated from left to right)
    Where 1<=x<=N.You are request to find out the output for M operations.
    Input
    Input contains multiple cases.
    Each test case starts with two integer N,M(1<=N,M<=50000) ,indicating that there are N units of memory and M operations.
    Follow by M lines,each line contains one operation as describe above.
    Output
    For each “Reset” operation, output “Reset Now”.
    For each “New” operation, if it’s possible to allocate a memory block,
    output “New at A”,where Ais the least start number,otherwise output “Reject New”.
    For each “Free” operation, if it’s possible to find a memory block occupy unit x,
    output “Free from A to B”,where A and B refer to the start and end number of the memory block,otherwise output “Reject Free”.
    For each “Get” operation, if it’s possible to find the xth memory blocks,
    output “Get at A”,where A is its start number,otherwise output “Reject Get”.
    Output one blank line after each test case.
    Sample Input
    6 10
    New 2
    New 5
    New 2
    New 2
    Free 3
    Get 1
    Get 2
    Get 3
    Free 3
    Reset
    Sample Output
    New at 1
    Reject New
    New at 3
    New at 5
    Free from 3 to 4
    Get at 1
    Get at 5
    Reject Get
    Reject Free
    Reset Now

题意:
连续内存单元称为内存块。
New x:尽量靠左的区域覆盖一个长为x的内存块
Free x: 释放x内存单元所在内存块
Get x: 返回第x个内存块的起始下标
Reset: 释放所有内存
思路:
线段树区间合并题目。比较不同的是本题是以“内存块“的形式存在,每一个块有个单独的标号,并且删除也是一块一块的操作。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 5e4 + 1005;

int cnt_num,cnt;
struct Node
{
    int l,r;
    int lsum,rsum,sum;
    int cover;
}t[maxn << 2],interval[maxn];
bool _hash[maxn];

void pushup(int i)
{
    if(t[i * 2].cover == -1 || t[i * 2 + 1].cover == -1)t[i].cover = -1;
    else if(t[i * 2].cover != t[i * 2 + 1].cover)t[i].cover = -1;
    else t[i].cover = t[i * 2].cover;
    
    t[i].sum = max(max(t[i * 2].sum,t[i * 2 + 1].sum),t[i * 2].rsum + t[i * 2 + 1].lsum);
    t[i].lsum = t[i * 2].lsum;
    if(t[i * 2].lsum == t[i * 2].r - t[i * 2].l + 1)t[i].lsum += t[i * 2 + 1].lsum;
    
    t[i].rsum = t[i * 2 + 1].rsum;
    if(t[i * 2 + 1].rsum == t[i * 2 + 1].r - t[i * 2 + 1].l + 1)t[i].rsum += t[i * 2].rsum;
}

void pushdown(int i)
{
    if(t[i].cover != -1)
    {
        t[i * 2].cover = t[i * 2 + 1].cover = t[i].cover;
        t[i * 2].lsum = t[i * 2].rsum = t[i * 2].sum = t[i].cover ? 0 : t[i * 2].r - t[i * 2].l + 1;
        t[i * 2 + 1].lsum = t[i * 2 + 1].rsum = t[i * 2 + 1].sum = t[i].cover ? 0 : t[i * 2 + 1].r - t[i * 2 + 1].l + 1;
    }
}

void build(int i,int l,int r)
{
    t[i].l = l;t[i].r = r;
    if(l == r)
    {
        t[i].lsum = t[i].rsum = t[i].sum = 1;
        t[i].cover = 0;
        return;
    }
    int m = (l + r) >> 1;
    build(i * 2,l,m);
    build(i * 2 + 1,m + 1,r);
    pushup(i);
}

void update(int i,int x,int y,int v)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        t[i].cover = v;
        t[i].lsum = t[i].rsum = t[i].sum = v ? 0 : t[i].r - t[i].l + 1;
        return;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)update(i * 2,x,y,v);
    if(y > m) update(i * 2 + 1,x,y,v);
    pushup(i);
}

void query_get(int i,int x)
{
    if(cnt >= x)return;
    if(t[i].cover != -1 || t[i].l == t[i].r)
    {
        if(t[i].cover && _hash[t[i].cover] == false)
        {
            _hash[t[i].cover] = true;
            cnt++;
        }
        if(cnt == x)cnt_num = t[i].cover;
        return;
    }
    query_get(i * 2,x);
    if(cnt >= x)return;
    query_get(i * 2 + 1,x);
}

int query(int i,int v)
{
    if(t[i].l == t[i].r)
    {
        return t[i].l;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    int res = 0;
    if(t[i * 2].sum >= v)res = query(i * 2,v);
    else if(t[i * 2].rsum + t[i * 2 + 1].lsum >= v)
    {
        res = m - t[i * 2].rsum + 1;
    }
    else res = query(i * 2 + 1,v);
    return res;
}

int query_free(int i,int x)
{
    if(t[i].cover != -1)
    {
        return t[i].cover;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)return query_free(i * 2,x);
    else return query_free(i * 2 + 1,x);
}



int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m) && n && m)
    {
        build(1,1,n);
        int all = 0;
        for(int i = 1;i <= m;i++)
        {
            char op[10];scanf("%s",op);
            if(op[0] == 'R')
            {
                all = 0;
                update(1,1,n,0);
                printf("Reset Now\n");
            }
            else if(op[0] == 'N')
            {
                int x;scanf("%d",&x);
                if(t[1].sum < x)printf("Reject New\n");
                else
                {
                    int pos = query(1,x);
                    printf("New at %d\n",pos);
                    update(1,pos,pos + x - 1,i);
                    interval[i].l = pos;interval[i].r = pos + x - 1;
                    all++;
                }
            }
            else if(op[0] == 'F')
            {
                int x;scanf("%d",&x);
                if(x > n || x <= 0)printf("Reject Free\n");
                else
                {
                    int id = query_free(1,x);
                    if(id == 0)printf("Reject Free\n");
                    else
                    {
                        int ql = interval[id].l,qr = interval[id].r;
                        printf("Free from %d to %d\n",ql,qr);
                        update(1,ql,qr,0);
                        all--;
                    }
                }
            }
            else if(op[0] == 'G')
            {
                int x;scanf("%d",&x);
                if(x > all)printf("Reject Get\n");
                else
                {
                    cnt_num = 0;cnt = 0;
                    memset(_hash,0,sizeof(_hash));
                    query_get(1,x);
                    printf("Get at %d\n",interval[cnt_num].l);
                }
            }
        }
        printf("\n");
    }
    return 0;
}

发布了628 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104065849