问题 2746 --P1146 2012

2746: P1146 2012

题目描述

          你开始写这个操作系统,它的第一个模块自然是内存管理程序。         计算机的可用内存被划分成N个内存单元,从1至N编号。在每一时刻,每个内存单元可能是“空闲”或“占用”这两种状态中的一种。开始时,所有单元的状态是“空闲”。         系统上运行的程序在某些时刻可能提交内存操作请求,它们是“分配”或者“查询”。         分配请求是程序希望得到一个空闲的内存单元。一些分配请求指定了请求的内存单元编号,这是你只需返回这次分配是否成功。只有在该时刻那一个单元是空闲的,我们说这个操作是成功的。另一些请求没有指定内存单元,你需要分配给它一个合适的。为了使系统有更高的效率,你应该分配所有空闲内存单元中最中间的那个。换而言之,空闲的内存单元为b1,b2,…,bx,则分配的单元编号为b(x/2)(x是偶数)或b[(x+1)/2](x是奇数)。如果没有空闲内存,应该返回失败信息。         查询请求是程序希望访问某一内存单元,但你不需要考虑它的内容是什么。只有在该时刻那个内存单元是占用的,程序才能访问它。否则,我们称之为“段异常”。         另外,这些超级计算机应该非常讲求效率。所以,每个内存单元都有一定的占用期限t0(秒),由分配该内存时的请求指定。占用期从当前时刻起计。占用期限结束后,该内存自动变为空闲状态。如果在占用期限内访问该内存,占用期限变更为此时刻起的t0秒。具体地说,在t时刻占用期限为t0的内存单元,其有效期为[t,t0+t)。         这就是你需要实现的全部内容。

输入

        输入的第一行有两个正整数N,M,M表示内存操作请求的个数。         以下M行,前两个元素为正整数t和字符opr(为’+’或’?’),t是提交请求的时刻。操作请求按t升序排列,如有相同则按在输入中的顺序处理。         若opr为'+',这是一条分配请求。此后有两个自然数p,t0,p是指定的内存单元编号。若p为0,表示你应该分配一个合适的内存单元(如题目所述)。         若opr为'?',这是一条查询请求。此后有一个正整数q,为查询的单元号。         每行中两元素间以空格分隔,行尾无空格。输入数据是正确的,不必检验。

输出

        输出有M行,每行对应一条操作请求的结果。         对于分配请求,如果指定了编号,输出”+”或”-”(不含双引号,下同),分别表示成功或失败。否则,输出一个正整数,为分配的内存单元编号。         对于查询请求,输出”+”或”-”,分别表示成功或失败。

样例输入输出

输入#1 复制
4 14
1 + 0 600
1 + 0 600
1 + 1 601
1 + 3 600
2 ? 2
2 ? 4
601 ? 1
601 ? 2
601 ? 3
601 + 0 602
601 + 0 600
601 + 0 600
1200 ? 1
2012 ? 3
输出#1 复制
2
3
+
-
+
-
+
+
-
3
4
-
+
-

提示

数据规模:对于20%的数据,所有p不为0。对于40%的数据,N< =1000,M< =5000。对于全部的数据,1< =N< =30000,1< =M< =100000,600< =t0< =60000,1< =t< =60000,1< =q< =N。

序号 标题 作者 发表时间 费用 订购数 操作