(线段树,二分)hdoj 2871-Memory Control

Posted 惜取少年时

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(线段树,二分)hdoj 2871-Memory Control相关的知识,希望对你有一定的参考价值。

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. 

InputInput 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. 
OutputFor 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

区间维护依旧与Hotel题目类似。变得更加复杂的是对Free get操作时区间的维护。采用引入vector记录区间的办法,为了提高效率,每次查询、插入都需要采用二分法(利用了vector插入时是在
给定地址前插入数据的特性)这种二分法的使用值得复习反思。
  1 #include <iostream>
  2 //#include<bits/stdc++.h>
  3 #include <stack>
  4 #include <queue>
  5 #include <map>
  6 #include <set>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <math.h>
 11 using namespace std;
 12 int N,M;
 13 const int MAX=5e4+5;
 14 struct node
 15 {
 16     int left,right,mid;
 17     int al,ar;
 18     int status;
 19     int len()
 20     {
 21         return ar-al+1;
 22     }
 23     void actl()
 24     {
 25         left=right=mid=(status?0:len());
 26     }
 27 }st[10*MAX];
 28 struct seg//记录区间
 29 {
 30     int left,right;
 31 };
 32 vector <seg> ve;//储存区间信息
 33 seg oh;//临时储存
 34 void init(int l,int r,int k)
 35 {
 36     st[k].al=l;
 37     st[k].ar=r;
 38     st[k].status=0;
 39     st[k].actl();
 40     if(l==r)
 41         return;
 42     init(l,(l+r)/2,2*k);
 43     init((l+r)/2+1,r,2*k+1);
 44 }
 45 void pushdown(int k)
 46 {
 47     if(st[k].status!=-1)
 48     {
 49         st[2*k].status=st[2*k+1].status=st[k].status;
 50         st[k].status=-1;
 51         st[2*k].actl();
 52         st[2*k+1].actl();
 53     }
 54 }
 55 int query(int len,int k)
 56 {
 57     if(len==1&&st[k].al==st[k].ar)
 58         return st[k].al;
 59     if(st[k].mid<len)
 60         return -1;
 61     pushdown(k);
 62     if(st[2*k].mid>=len)
 63         return query(len,2*k);
 64     else if(st[2*k].right+st[2*k+1].left>=len)
 65         return st[2*k].ar-st[2*k].right+1;
 66     else if(st[2*k+1].mid>=len)
 67         return query(len,2*k+1);
 68     return -1;
 69 }
 70 void update(int ul,int ur,int l,int r,int k,int val)
 71 {
 72     if(l==ul&&r==ur)
 73     {
 74         st[k].status=val;
 75         st[k].actl();
 76         return;
 77     }
 78     if(l==r)
 79         return;
 80     pushdown(k);
 81     int mid=(l+r)/2;
 82     if(ur<=mid)
 83         update(ul,ur,l,mid,2*k,val);
 84     else if(ul>mid)
 85         update(ul,ur,mid+1,r,2*k+1,val);
 86     else
 87     {
 88         update(ul,mid,l,mid,2*k,val);
 89         update(mid+1,ur,mid+1,r,2*k+1,val);
 90     }
 91     st[k].mid=max(st[2*k].mid,st[2*k+1].mid);
 92     st[k].left=st[2*k].left;
 93     st[k].right=st[2*k+1].right;
 94     st[k].mid=max(st[2*k].right+st[2*k+1].left,st[k].mid);
 95     if(st[2*k].left==st[2*k].len())
 96         st[k].left+=st[2*k+1].left;
 97     if(st[2*k+1].right==st[2*k+1].len())
 98         st[k].right+=st[2*k].right;
 99     return;
100 }
101 char command[10];
102 int tem,an;
103 int lo;//添加的位置
104 int binarysearch(int k)
105 {
106     int l,r,mid;
107     l=0;r=ve.size()-1;
108     while(l<=r)
109     {
110         mid=(l+r)/2;
111         if(ve[mid].left<=k)
112             l=mid+1;
113         else if(ve[mid].left>k)
114             r=mid-1;
115     }
116     return l;
117 }
118 int main()
119 {
120     while(~scanf("%d %d",&N,&M))
121     {
122         ve.clear();
123         init(1,N,1);
124         while(M--)
125         {
126             scanf("%s",command);
127             if(command[0]==R)
128             {
129                 ve.clear();
130                 st[1].status=0;
131                 st[1].actl();
132                 pushdown(1);
133                 printf("Reset Now\n");
134             }
135             else if(command[0]==N)
136             {
137                 scanf("%d",&tem);
138                 an=query(tem,1);
139                 if(an==-1)
140                     printf("Reject New\n");
141                 else
142                 {
143                     oh.left=an;oh.right=an+tem-1;
144                     lo=binarysearch(an);
145                     ve.insert(ve.begin()+lo,oh);
146 
147                     update(an,an+tem-1,1,N,1,1);
148                     printf("New at %d\n",an);
149                 }
150             }
151             else if(command[0]==F)
152             {
153                 scanf("%d",&tem);
154                 lo=binarysearch(tem)-1;
155                 if(lo<=-1||ve[lo].right<tem)
156                     printf("Reject Free\n");
157                 else
158                 {
159                     update(ve[lo].left,ve[lo].right,1,N,1,0);
160                     printf("Free from %d to %d\n",ve[lo].left,ve[lo].right);
161                     ve.erase(ve.begin()+lo,ve.begin()+lo+1);//删除掉ve中的这个seg区间
162                 }
163             }
164             else if(command[0]==G)
165             {
166                 scanf("%d",&tem);
167                 if(tem>ve.size())
168                     printf("Reject Get\n");
169                 else
170                 {
171                     printf("Get at %d\n",ve[tem-1].left);
172                 }
173             }
174         }
175         printf("\n");//题意要求两组数据之间换行
176     }
177 }

 

 

以上是关于(线段树,二分)hdoj 2871-Memory Control的主要内容,如果未能解决你的问题,请参考以下文章

hdoj 4325 Flowers 线段树+离散化

HDOJ5875(线段树)

(线段树)hdoj 3308-LCIS

[hdoj4578][多延迟标记的线段树]

[HDOJ1828]Picture(扫描线,线段树,矩形并周长)

HDOJ 5306 Gorgeous Sequence 线段树