hdu 2871 Memory Control
题目描述:
给定连续的内存块,支持4个操作:
1.申请连续长为x的空间,并且返回这段区间的左端点。
2.释放包含x的内存块。
3.询问从左到右第x块的区间范围。
4.重置。
分析:
和poj3667比较像,只是多了3 4的操作。
我开了两个线段树,第一个成段更新,为了记录每一段的颜色(其实就是第几次申请时被占用的),第二个记录每一段起点,这是为了方便操作3的查询。
最后reset的时候传一个懒惰标记就行。。重新build会超时
p.s.数组大小随便开的。。。其实可以小点。。无视就好
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #define N 100010 6 #define lson l,m,n<<1 7 #define rson m+1,r,n<<1|1 8 #pragma comment(linker, "/STACK:102400000,102400000") 9 using namespace std; 10 int st[N<<1],len[N<<1]; 11 struct segtree1{ 12 int s[N<<2][3],cnt[N<<2]; 13 inline void pushdown(int n,int m){ 14 if(cnt[n]!=-1){ 15 cnt[n<<1]=cnt[n<<1|1]=cnt[n]; 16 s[n<<1][0]=s[n<<1][1]=s[n<<1][2]=cnt[n]?0:(m-(m>>1)); 17 s[n<<1|1][0]=s[n<<1|1][1]=s[n<<1|1][2]=cnt[n]?0:(m>>1); 18 cnt[n]=-1; 19 } 20 } 21 inline void pushup(int n,int m){ 22 s[n][0]=s[n<<1][0]; 23 if(s[n][0]==(m-(m>>1))) 24 s[n][0]+=s[n<<1|1][0]; 25 s[n][1]=s[n<<1|1][1]; 26 if(s[n][1]==(m>>1)) 27 s[n][1]+=s[n<<1][1]; 28 s[n][2]=max(max(s[n<<1][2],s[n<<1|1][2]),s[n<<1][1]+s[n<<1|1][0]); 29 } 30 void build(int l,int r,int n){ 31 s[n][0]=s[n][1]=s[n][2]=r-l+1; 32 cnt[n]=-1; 33 if(l==r)return; 34 int m=(l+r)>>1; 35 build(lson); 36 build(rson); 37 } 38 void update(int ll,int rr,int f,int l,int r,int n){ 39 if(ll==l&&rr==r){ 40 cnt[n]=f; 41 s[n][0]=s[n][1]=s[n][2]=f?0:(r-l+1); 42 return; 43 } 44 int m=(l+r)>>1; 45 pushdown(n,r-l+1); 46 if(rr<=m)update(ll,rr,f,lson); 47 else if(ll>m)update(ll,rr,f,rson); 48 else update(ll,m,f,lson),update(m+1,rr,f,rson); 49 pushup(n,r-l+1); 50 } 51 int queryc(int nn,int l,int r,int n){ 52 if(l==r)return cnt[n]; 53 pushdown(n,r-l+1); 54 int m=(l+r)>>1; 55 if(nn<=m)return queryc(nn,lson); 56 else return queryc(nn,rson); 57 } 58 int query(int nn,int l,int r,int n){ 59 if(l==r)return l; 60 int m=(l+r)>>1; 61 pushdown(n,r-l+1); 62 if(s[n<<1][2]>=nn) 63 return query(nn,lson); 64 else if(s[n<<1][1]+s[n<<1|1][0]>=nn) 65 return m-s[n<<1][1]+1; 66 else 67 return query(nn,rson); 68 } 69 }a; 70 71 struct segtree2{ 72 int s[N<<2],flag[N<<2]; 73 inline void pushup(int n){ 74 s[n]=s[n<<1]+s[n<<1|1]; 75 } 76 inline void pushdown(int n){ 77 if(flag[n]!=-1){ 78 flag[n<<1]=flag[n<<1|1]=flag[n]; 79 s[n<<1]=s[n<<1|1]=flag[n]; 80 flag[n]=-1; 81 } 82 } 83 void build(int l,int r,int n){ 84 s[n]=0;flag[n]=-1; 85 if(l==r)return; 86 int m=(l+r)>>1; 87 build(lson); 88 build(rson); 89 } 90 void update(int ll,int rr,int f,int l,int r,int n){ 91 if(ll==l&&rr==r){ 92 s[n]=f; 93 flag[n]=f; 94 return; 95 } 96 pushdown(n); 97 int m=(l+r)>>1; 98 if(rr<=m)update(ll,rr,f,lson); 99 else if(ll>m)update(ll,rr,f,rson); 100 else update(ll,m,f,lson),update(m+1,rr,f,rson); 101 pushup(n); 102 } 103 int query(int nn,int l,int r,int n){ 104 if(l==r)return l; 105 pushdown(n); 106 int m=(l+r)>>1; 107 if(s[n<<1]>=nn)return query(nn,lson); 108 else 109 return query(nn-s[n<<1],rson); 110 } 111 }b; 112 113 int main(){ 114 int n,m; 115 while(~scanf("%d%d",&n,&m)){ 116 a.build(1,n,1); 117 b.build(1,n,1); 118 int cnt=0; 119 char op[10]; 120 int x; 121 while(m--){ 122 scanf("%s",op); 123 if(op[0]=='N'){ 124 scanf("%d",&x); 125 if(a.s[1][2]<x)puts("Reject New"); 126 else{ 127 int ans=a.query(x,1,n,1); 128 st[++cnt]=ans; 129 len[cnt]=x; 130 printf("New at %d\n",ans); 131 a.update(ans,ans+x-1,cnt,1,n,1); 132 b.update(ans,ans,1,1,n,1); 133 } 134 }else if(op[0]=='F'){ 135 scanf("%d",&x); 136 int ans=a.queryc(x,1,n,1); 137 if(ans<=0)puts("Reject Free"); 138 else{ 139 printf("Free from %d to %d\n",st[ans],st[ans]+len[ans]-1); 140 a.update(st[ans],st[ans]+len[ans]-1,0,1,n,1); 141 b.update(st[ans],st[ans],0,1,n,1); 142 } 143 }else if(op[0]=='G'){ 144 scanf("%d",&x); 145 if(b.s[1]<x)puts("Reject Get"); 146 else{ 147 int ans=b.query(x,1,n,1); 148 printf("Get at %d\n",ans); 149 } 150 }else if(op[0]=='R'){ 151 puts("Reset Now"); 152 a.update(1,n,0,1,n,1); 153 b.update(1,n,0,1,n,1); 154 } 155 } 156 puts(""); 157 } 158 return 0; 159 }