zoukankan      html  css  js  c++  java
  • hdu 2871 Memory Control

    Memory Control

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3610    Accepted Submission(s): 841


    Problem Description
    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
     
    Source
     
    /*
    
    内存控制
    4种操作:
    1.Reset 初始化
    2.New x 开辟长度为x的连续的空间,输出起始位置
    3.Free x 释放包含第x字节的块,整块都释放掉
    4.Get x  输出当前状态下,内存里第x块的起始位置
    
    思路:
    1.Reset 很简单,update(1,N,EMPTY,1);就可以了
            没有必要重新构树
    
    2.New  x 对于这个操作,和Hotel这道题是一样的。
            建立树的过程中保存了lmax,rmax,max。在查询的
            过程中有一些小的技巧。
    
    3.Free x 释放内存,开一个容器,维护这个容器的顺序。
            学到了很多容器的知识。海,以前没有学过容器
            还是学别人的。
    4.Get x 也是通过维护这个容器,来得到的。
    
    详细的见代码
    
    
    */
    
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #define EMPTY 2 //纯色  此题中代表  空的。
    #define HH 1 //混色  此题中代表 被占用了。
    using namespace std;
    
    
    
    struct node
    {
        int l;
        int r;
        int lmax,rmax,max;
        int len;
        int color;
    }f[50003*4];
    struct st
    {
        int begin;
        int end;
    };
    vector<st>tom;
    
    
    int hmax(int x,int y)
    {
        return x>y? x:y;
    }
    
    bool cmp1(st n1,st n2)
    {
        return n1.begin<n2.begin;
    }
    
    void build(int l,int r,int n) //建树。
    {
        int mid=(l+r)/2;
        f[n].l=l;
        f[n].r=r;
        f[n].color=0;
        f[n].len=f[n].r-f[n].l+1;
        f[n].lmax=f[n].rmax=f[n].max=f[n].len;
        if(l==r)
        return;
        build(l,mid,n*2);
        build(mid+1,r,n*2+1);
    }
    /*
    建设的过程也有一个小小的亮点,可以把
     f[n].lmax=f[n].rmax=f[n].max=f[n].len;
     用向上更新来写在build(mid+1,r,n*2+1)后,带上
    */
    
    void make_down(int n) //向下更新
    {
        if(f[n].color==EMPTY)
        {
            f[n*2].max=f[n*2].rmax=f[n*2].lmax=f[n*2].len;
            f[n*2+1].max=f[n*2+1].rmax=f[n*2+1].lmax=f[n*2+1].len;
        }
        else if(f[n].color==HH)
        {
            f[n*2].max=f[n*2].lmax=f[n*2].rmax=0;
            f[n*2+1].max=f[n*2+1].lmax=f[n*2+1].rmax=0;
        }
    
        f[n*2].color=f[n].color;
        f[n*2+1].color=f[n].color;
    
        f[n].color=0;
        f[n].lmax=f[n].rmax=f[n].max=0;
    
    }
    
    void make_up(node *father,node *l_child,node *r_child) //向上更新
    {
        father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax: l_child->lmax;
        father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax: r_child->rmax;
        father->max=hmax(hmax(father->lmax,father->rmax),
                         hmax(l_child->max,
                              hmax(r_child->max,l_child->rmax+r_child->lmax)));
    }
    //为什么这道题,有个小小的亮点,没有rnum ,lnum;
    //仔细一想确实是不需要的..
    
    
    
    void update(int l,int r,int num,int n) //更新函数  区间[l,r],更新为num。
    {
        int mid=(f[n].l+f[n].r)/2;
        if(f[n].l==l && f[n].r==r)
        {
            if(num==EMPTY)
            {
                f[n].lmax=f[n].rmax=f[n].max=f[n].len;
            }
            else f[n].lmax=f[n].rmax=f[n].max=0;
            f[n].color=num;
            return;
        }
    
        if(f[n].color!=0)
        make_down(n);
        if(mid>=r)
        update(l,r,num,n*2);
        else if(mid<l)
        update(l,r,num,n*2+1);
        else
        {
            update(l,mid,num,n*2);
            update(mid+1,r,num,n*2+1);
        }
        make_up(&f[n],&f[n*2],&f[n*2+1]);
    }
    
    int query(int max,int n)
    {
        int cur=0;
    
        if(f[n].l==f[n].r)
        return f[n].l;
        if(f[n].color!=0) //刚开始,这个别丢了,居然Running time error。
        make_down(n);
    
        if(f[n*2].max>=max)
        cur=query(max,n*2);
    
        else if(f[n*2].rmax+f[n*2+1].lmax>=max)
        return f[n*2].r-f[n*2].rmax+1;
    
        else if(f[n*2+1].max>=max)
        cur=query(max,n*2+1);
    
        make_up(&f[n],&f[n*2],&f[n*2+1]);
        return cur;
    }
    /*
    刚开始    左子树,
    然后是    左子树右边最大值+右子树左边最大值
    最后才是  右子树
    */
    
    void make_ini(int N,int M)
    {
        char a[10];
        int x,l,r,tmp;
        st hxl;
        while(M--)
        {
            scanf("%s",a);
            if(a[0]=='R')
            {
                update(1,N,EMPTY,1);
                tom.clear();
                printf("Reset Now
    ");
            }
            if(a[0]=='N')
            {
                scanf("%d",&x);
                if(f[1].max<x)
                {
                    printf("Reject New
    ");
                }
                else
                {
                    l=query(x,1);
                    r=l+x-1;
                    hxl.begin=l;
                    hxl.end=r;
                    vector<st>::iterator it;
                    it=upper_bound(tom.begin(),tom.end(),hxl,cmp1);//二分查找,前提是有序。
                    tom.insert(it,hxl);
                    printf("New at %d
    ",l);
                    update(l,r,HH,1);
                }
            }
            else if(a[0]=='F')
            {
                scanf("%d",&x);
                hxl.begin=x;
                hxl.end=x;
                vector<st>::iterator it;//容器的使用啊
                it=upper_bound(tom.begin(),tom.end(),hxl,cmp1);
    
                tmp=it-tom.begin()-1;
                if(tmp==-1 || tom[tmp].end<x)
                printf("Reject Free
    ");
                else
                {
                    printf("Free from %d to %d
    ",tom[tmp].begin,tom[tmp].end);
                    update(tom[tmp].begin,tom[tmp].end,EMPTY,1);
                    tom.erase(tom.begin()+tmp);
                }
            }
            else if(a[0]=='G')
            {
                scanf("%d",&x);
                if(x>tom.size())
                printf("Reject Get
    ");
                else
                printf("Get at %d
    ",tom[x-1].begin);//容器的下标也是从0开始,所以要减1
            }
        }
    }
    
    int main()
    {
        int N,M;
        while(scanf("%d%d",&N,&M)>0)
        {
            tom.clear();//这个必须要的。
            build(1,N,1);
            make_ini(N,M);
            printf("
    "); //!!
        }
        return 0;
    }
  • 相关阅读:
    使用Lua编写Wireshark插件解析KCP UDP包,解析视频RTP包
    开源自己用python封装的一个Windows GUI(UI Automation)自动化工具,支持MFC,Windows Forms,WPF,Metro,Qt
    2019 WebRtc AudioMixer混音流程
    记录一次定位视频通话 音视频卡顿的原因分析过程。
    C++标准库里自带的数值类型和字符串互相转换函数
    C++ raw string literal
    使用multiprocessing解决PyMuPDF不支持多线程加载导致的界面卡死无响应问题,及一个PyQt5实现的简易PDF阅读器例子
    使用ctypes调用系统C API函数需要注意的问题,函数参数中有指针或结构体的情况下最好不要修改argtypes
    使用python uiautomation从钉钉网页版提取公司所有联系人信息
    使用python UIAutomation从QQ2017(v8.9)群界面获取所有群成员详细资料,
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3230366.html
Copyright © 2011-2022 走看看