题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2871
题意:给你一段内存,让你操作1:Reset:重置所有内存 2:New x:申请一块X大小的内存,返回内存最左边的开头,3:free x:释放包含x单元的内存块 4:Get x:取第X块的内存首地址
题解:这题我写了一晚上,很恶心,显然用线段树维护,不过用一个Vector 来应对 free和get操作比较方便,线段树就只需要维护内存的连续长度和最大长度就行了,
ll[rt]为该区段从左边开始的连续内存长度,rr[rt]为该区间从右边开始的连续内存长度,mlen[rt]为该区间最大的连续内存长度,只有这样维护才能在线段树中任意操作区间
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 #define F(i,a,b) for(int i=a;i<=b;i++) 6 #define root 1,n,1 7 #define ls l,m,rt<<1 8 #define rs m+1,r,rt<<1|1 9 #define Max(a,b) ((a)>(b)?(a):(b)) 10 11 struct edge{ 12 int l,r; 13 bool operator<(const edge &b)const{return l<b.l;} 14 }s,e,tp; 15 const int maxn=50010; 16 int n,m,num,ll[maxn<<2],rr[maxn<<2],lazy[maxn<<2],mlen[maxn<<2]; 17 vector<edge>Q; 18 19 inline void pup(int l,int r,int rt){ 20 int m=(l+r)>>1; 21 mlen[rt]=Max(mlen[rt<<1],mlen[rt<<1|1]); 22 mlen[rt]=Max(mlen[rt],rr[rt<<1]+ll[rt<<1|1]); 23 ll[rt]=ll[rt<<1]+(ll[rt<<1]==m-l+1?ll[rt<<1|1]:0); 24 rr[rt]=rr[rt<<1|1]+(rr[rt<<1|1]==r-m?rr[rt<<1]:0); 25 } 26 27 inline void pdown(int l,int r,int rt){ 28 if(lazy[rt]!=-1){ 29 lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; 30 int m=(l+r)>>1; 31 mlen[rt<<1]=ll[rt<<1]=rr[rt<<1]=(lazy[rt]==0?m-l+1:0); 32 mlen[rt<<1|1]=rr[rt<<1|1]=ll[rt<<1|1]=(lazy[rt]==0?r-m:0); 33 lazy[rt]=-1; 34 } 35 } 36 37 int New(int l,int r,int rt,int num){ 38 if(l==r)return l; 39 int m=(l+r)>>1; 40 pdown(l,r,rt); 41 if(mlen[rt<<1]>=num)return New(ls,num); 42 else if(rr[rt<<1]+ll[rt<<1|1]>=num)return m-rr[rt<<1]+1; 43 else return New(rs,num); 44 } 45 46 void covr(int op,int L,int R,int l,int r,int rt){//op为0是释放内存,1为占用 47 if(L<=l&&r<=R){ 48 lazy[rt]=op,ll[rt]=rr[rt]=mlen[rt]=(op==0?r-l+1:0); 49 return; 50 } 51 pdown(l,r,rt); 52 int m=(l+r)>>1; 53 if(L<=m)covr(op,L,R,ls); 54 if(R>m)covr(op,L,R,rs); 55 pup(l,r,rt); 56 } 57 58 void reset(){Q.clear(),Q.push_back(s),Q.push_back(e);covr(0,1,n,root);} 59 60 void insert(edge xx){ 61 int now=upper_bound(Q.begin(),Q.end(),xx)-Q.begin(); 62 Q.insert(Q.begin()+now,xx); 63 } 64 65 int main(){ 66 char op[20];s.l=0,s.r=0,e.l=100000,e.r=100000; 67 while(~scanf("%d%d",&n,&m)){ 68 reset(); 69 while(m--){ 70 scanf("%s",op); 71 if(op[0]!='R')scanf("%d",&num); 72 if(op[0]=='N')if(mlen[1]<num)puts("Reject New"); 73 else{int x=New(root,num);printf("New at %d ",x),tp.l=x,tp.r=x+num-1,covr(1,tp.l,tp.r,root),insert(tp);} 74 else if(op[0]=='F'){ 75 tp.l=num,tp.r=num; 76 int now=upper_bound(Q.begin(),Q.end(),tp)-Q.begin()-1; 77 if(Q[now].l<=num&&Q[now].r>=num) 78 covr(0,Q[now].l,Q[now].r,root),printf("Free from %d to %d ",Q[now].l,Q[now].r),Q.erase(Q.begin()+now); 79 else puts("Reject Free"); 80 }else if(op[0]=='G'){ 81 if(num>Q.size()-2)puts("Reject Get"); 82 else printf("Get at %d ",Q[num].l); 83 }else reset(),puts("Reset Now"); 84 } 85 puts(""); 86 } 87 return 0; 88 }