Memory Control HDU 2871

 

题意:模拟存储空间的申请和释放,共四种操作:

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

(申请一个大小为X个单元的连续存储区间,要求从存储区间的最靠左的地方申请)
3.  Free x Release the memory block which includes unit x

(释放包含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)

 (获得第X个区间的起始位置)

 

题解:线段树。(此题是POJ Hotel的加强版)

此题难点在于操作3--释放包含X单元的存储区间,这就要获得该区间的起止位置,然后再更新。由于每次申请存储空间(New X)的时候都知道该区间的起止位置,所以我们可以把它们记录在vector数组里并同时维护数组的顺序,当要Free X时直接二分查找X包含在哪个区间里,然后再更新线段树和vector数组。因为vector数组可在中间进行插入删除操作,所以维护数组顺序就方便多了。

 

总结:此题虽说没什么难的,但代码敲完还是bug百出啊!!!主要是由于考虑不全,漏了一些操作 TT^TT 。。。这里说下此题要注意的地方。

对于New x没什么好说的,线段树查找到最左端的能连续申请X个单元的区间起始位置,再对线段树进行更新并将其插入到vector数组中的相应位置。

对于Free X操作,首先要利用vector进行二分查找找到包含X的区间的起止位置,然后再对线段树进行更新并将相应数据从vector数组中删除。(这里我开了两个vector数组分别存放区间的起始位置和终止位置,当然只开一个也可以。。。)

Get X 就更简单了,首先判断有没有X个区间,有点话直接输出vector中相应的左右区间,没有就Reject啦。。

Reset 也很简单了,对线段树的根节点处理一下,延迟标记一下表示对区间清0,再将vector clear()一下即可。

 

在写程序的时候出现的一个bug我不得不吐槽一下,在Reset时我觉得进行以上操作就可以了,但提交以后一直RE。。。不断增大线段树的大小直到爆内存了也还是RE。。。后来就一行一行的检查,最后终于发现造成RE的原因:

1 else if(!strcmp(s,"Free")){
2                 scanf("%d",&x);
3                 if(B_search(x,0,bnum-1)){//这里如果之前Reset了话,调用B_search()会造成非法访问vector数组,因此就会RE! 
4                     printf("Free from %d to %d\n",lv,rv);
5                     updata(0,lv,rv,1,n,1);
6                     bnum--;
7                 }
8                 else printf("Reject Free\n");
9             }

如果改成下面的就正确了。

1 if(bnum&&B_search(x,0,bnum-1))

bnum是申请内存的个数。SB的是找到错误之后太激动了,就直接在“B_search()”后加了个“&&bnum”,结果有RE了,顺序倒了执行的先后顺序就不一样,跟没加一样。。改在前面提交就A了。。。对于这种题都A的这么艰难,还是弱啊。。。

 

 AC代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #define lson l,m,rt<<1
  7 #define rson m+1,r,rt<<1|1
  8 using namespace std;
  9 
 10 const int maxn=55555;
 11 int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2],cov[maxn<<2];
 12 int lv,rv,bnum;
 13 vector<int>v1,v2;
 14 
 15 int max(int a,int b){
 16     return a>b?a:b;
 17 }
 18 
 19 void pushUp(int rt,int len){
 20     lsum[rt]=lsum[rt<<1];
 21     rsum[rt]=rsum[rt<<1|1];
 22     msum[rt]=max(msum[rt<<1],msum[rt<<1|1]);
 23     if(lsum[rt]==len-(len>>1)) lsum[rt]+=lsum[rt<<1|1];
 24     if(rsum[rt]==(len>>1))     rsum[rt]+=rsum[rt<<1];
 25     msum[rt]=max(msum[rt],lsum[rt<<1|1]+rsum[rt<<1]);
 26 }
 27 
 28 void build(int l,int r,int rt){
 29     cov[rt]=-1;
 30     if(l==r){
 31         lsum[rt]=rsum[rt]=msum[rt]=1;
 32         return ;
 33     }
 34     int m=(l+r)>>1;
 35     build(lson);
 36     build(rson);
 37     pushUp(rt,r-l+1);
 38 }
 39 
 40 void pushDown(int rt,int len){
 41     if(cov[rt]==1) lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=0;
 42     else {
 43         lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=len-(len>>1);
 44         rsum[rt<<1|1]=lsum[rt<<1|1]=msum[rt<<1|1]=(len>>1);
 45     }
 46     cov[rt<<1]=cov[rt<<1|1]=cov[rt];
 47     cov[rt]=-1;
 48 }
 49 
 50 int query(int x,int l,int r,int rt){
 51     if(l==r) return l;
 52     if(cov[rt]!=-1) pushDown(rt,r-l+1);
 53     int m=(l+r)>>1;
 54     if(msum[rt<<1]>=x) return query(x,lson);
 55     if(rsum[rt<<1]+lsum[rt<<1|1]>=x) return m-rsum[rt<<1]+1;
 56     return query(x,rson);
 57 }
 58 
 59 void updata(int op,int L,int R,int l,int r,int rt){
 60     if(L<=l&&r<=R){
 61         cov[rt]=op;
 62         if(op==1) lsum[rt]=rsum[rt]=msum[rt]=0;
 63         else lsum[rt]=rsum[rt]=msum[rt]=r-l+1;
 64         return ;
 65     }
 66     if(cov[rt]!=-1) pushDown(rt,r-l+1);
 67     int m=(l+r)>>1;
 68     if(R<=m) updata(op,L,R,lson);
 69     else if(L>m) updata(op,L,R,rson);
 70     else{
 71         updata(op,L,R,lson);
 72         updata(op,L,R,rson);
 73     }
 74     pushUp(rt,r-l+1);
 75 }
 76 
 77 bool B_search(int x,int l,int r){
 78     int m;
 79     while(l<r){
 80         m=(l+r)>>1;
 81         if(v2[m]<x) l=m+1;
 82         else        r=m;
 83     }
 84     if(v1[l]<=x&&v2[l]>=x){
 85         lv=v1[l];
 86         rv=v2[l];
 87         v1.erase(v1.begin()+l);
 88         v2.erase(v2.begin()+l);
 89         return true;
 90     }
 91     return false;
 92 }
 93 
 94 int Binary_search(int num,int l,int r){
 95     int m;
 96     while(l<r){
 97         m=(l+r)>>1;
 98         if(v1[m]<num) l=m+1;
 99         else          r=m;
100     }
101     return l;
102 }
103 
104 int main()
105 {
106     //freopen("in.txt","r",stdin);
107     int n,m,x;
108     char s[10];
109     while(scanf("%d %d",&n,&m)!=EOF){
110         bnum=0;
111         v1.clear();
112         v2.clear();
113         build(1,n,1);
114         while(m--){
115             scanf("%s",s);
116             if(!(strcmp(s,"New"))){
117                 scanf("%d",&x);
118                 if(msum[1]<x) printf("Reject New\n");
119                 else{
120                     bnum++;
121                     lv=query(x,1,n,1);
122                     if(v1.empty()||lv>v1[bnum-2]){
123                         v1.push_back(lv);
124                         v2.push_back(lv+x-1);
125                     }
126                     else{
127                         int pos=Binary_search(lv,0,bnum-2);
128                         v1.insert(v1.begin()+pos,lv);
129                         v2.insert(v2.begin()+pos,lv+x-1);
130                     }
131                     updata(1,lv,lv+x-1,1,n,1);
132                     printf("New at %d\n",lv);
133                 }
134             }
135             else if(!strcmp(s,"Free")){
136                 scanf("%d",&x);
137                 if(bnum&&B_search(x,0,bnum-1)){//RE原因!!! 
138                     printf("Free from %d to %d\n",lv,rv);
139                     updata(0,lv,rv,1,n,1);
140                     bnum--;
141                 }
142                 else printf("Reject Free\n");
143             }
144             else if(!(strcmp(s,"Get"))){
145                 scanf("%d",&x);
146                 if(x>bnum) printf("Reject Get\n");
147                 else printf("Get at %d\n",v1[x-1]);
148             }
149             else if(!strcmp(s,"Reset")){
150                 bnum=0;
151                 lsum[1]=rsum[1]=msum[1]=n;
152                 cov[1]=0;
153                 v1.clear();
154                 v2.clear();
155                 printf("Reset Now\n");
156             }
157         }
158         printf("\n");
159     }
160     return 0;
161 }

 

 

 

posted on 2012-11-20 17:26  Acmer_Roney  阅读(237)  评论(0编辑  收藏  举报

导航