hdu_2871_Memory Control(巨恶心线段树)

题目连接: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 }
View Code




原文地址:https://www.cnblogs.com/bin-gege/p/5696133.html