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) 编辑 收藏 举报