HDU 2871 Memory Control

裸线段树区间合并,一开始没注意题目细节结果搞麻烦了……

给你四种操作,每种操作按它的要求输出结果。

1.  Reset Reset all memory units free. 

Reset 释放所有的内存

2.  New x Allocate a memory block consisted of x continuous free memory units with the least start number

New x   申请一个包含x个连续内存单元的内存块,起始地址编号最小

3.  Free x Release the memory block which includes unit x

Free x  释放包含地址x的内存块

(这个地方有个注意点可以从样例中得到,就是说如果我先申请了内存块1-2,后申请了内存块3-4,虽然1-4此时都被申请了,但1-4并不属于一个连续的内存块,因为它不是被一次申请的。如果查询4所在的内存块的起始地址,应当输出3,而不是1 )

4.  Get x Return the start number of the xth memory block(Note that we count the memory blocks allocated from left to right)

Get x 返回第x个内存块的起始地址(假定我们将内存块从左到右编号)

因为把题意的细节理解的有问题,所以一开始我的线段树不只是记录了连续的空余区间长度,还把连续被申请的区间长度也记录了,事实证明这是完全没必要。然后就去掉了。

还有一个地方是用一个vector来记录一下已经申请的内存块,因为要用二分查找,所以在向vector中插入元素时应注意维护一下它的有序性。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <vector>
  6 
  7 using namespace std;
  8 
  9 #define lc rt << 1
 10 #define rc rt << 1 | 1
 11 #define lson l, m, rt << 1
 12 #define rson m + 1, r, rt << 1 | 1
 13 
 14 const int MAXN = 50002;
 15 
 16 struct node
 17 {
 18     int st, ed;
 19     node(){}
 20     node( int _st, int _ed ) : st( _st ), ed( _ed ) { }
 21 };
 22 
 23 vector<node> blocks;
 24 
 25 int N, Q;
 26 int len[ MAXN << 2 ];    //空闲区最长连续长度
 27 
 28 int Llen[ MAXN << 2 ];   //左端空闲区长度
 29 int Rlen[ MAXN << 2 ];   //右端空闲区长度
 30 
 31 int flag[ MAXN << 2 ];   //0 释放  -1  无标记   1 占用
 32 
 33 bool lbd[ MAXN << 2 ];   //左端点是否空闲
 34 bool rbd[ MAXN << 2 ];   //右端点是否空闲
 35 
 36 void chuli( int op, int rt, int l, int r )
 37 {
 38     if ( op == 0 )
 39         Llen[rt] = Rlen[rt] = len[rt] = r - l + 1;
 40     else
 41         Llen[rt] = Rlen[rt] = len[rt] = 0;
 42 
 43     lbd[rt] = rbd[rt] = op ^ 1;
 44     return;
 45 }
 46 
 47 void PushDown( int rt, int l, int r, int m )
 48 {
 49     if ( flag[rt] != -1 )
 50     {
 51         flag[lc] = flag[rc] = flag[rt];
 52         chuli( flag[lc], lc, l, m );
 53         chuli( flag[rc], rc, m + 1, r );
 54         flag[rt] = -1;
 55     }
 56     return;
 57 }
 58 
 59 void PushUp( int rt, int l, int r, int m )
 60 {
 61     lbd[rt] = lbd[lc];
 62     rbd[rt] = rbd[rc];
 63 
 64     Llen[rt] = Llen[lc];
 65     Rlen[rt] = Rlen[rc];
 66 
 67     if ( Llen[lc] == m - l + 1 ) Llen[rt] += Llen[rc];
 68     if ( Rlen[rc] == r - m )     Rlen[rt] += Rlen[lc];
 69 
 70     len[rt] = max( len[lc], len[rc] );
 71     if ( lbd[rc] && rbd[lc] ) len[rt] = max( len[rt], Llen[rc] + Rlen[lc] );
 72 
 73     return;
 74 }
 75 
 76 void build( int l, int r, int rt )
 77 {
 78     flag[rt] = -1;
 79     if ( l == r )
 80     {
 81         len[rt] = Llen[rt] = Rlen[rt] = 1;
 82         lbd[rt] = rbd[rt] = true;
 83         return;
 84     }
 85 
 86     int m = ( l + r ) >> 1;
 87     build( lson );
 88     build( rson );
 89     PushUp( rt, l, r, m );
 90 
 91     return;
 92 }
 93 
 94 void Update( int L, int R, int op, int l, int r, int rt )
 95 {
 96     int m = ( l + r ) >> 1;
 97     if ( L <= l && r <= R )
 98     {
 99         flag[rt] = op;
100         chuli( op, rt, l, r );
101         return;
102     }
103     PushDown( rt, l, r, m );
104 
105     if ( L <= m ) Update( L, R, op, lson );
106     if ( R > m )  Update( L, R, op, rson );
107 
108     PushUp( rt, l, r, m );
109 
110     return;
111 }
112 
113 int Query( int a, int op, int l, int r, int rt )  //op代表查询空闲区间还是占用区间
114 {
115     int m = ( l + r ) >> 1;
116 
117     if ( l == r )
118     {
119         if ( len[rt] == a ) return l;
120         else return 0;
121     }
122 
123     PushDown( rt, l, r, m );
124 
125     if ( len[lc] >= a ) return Query( a, op, lson );
126     else if ( Rlen[lc] + Llen[rc] >= a ) return m - Rlen[lc] + 1;
127     else if ( len[rc] >= a ) return Query( a, op, rson );
128     else return 0;
129 }
130 
131 int BiSearch( int tar )
132 {
133     int low = 0, high = blocks.size() - 1, mid;
134     while ( low <= high )
135     {
136         mid = ( low + high ) >> 1;
137         if ( blocks[mid].st <= tar ) low = mid + 1;
138         else high = mid - 1;
139     }
140     return low;
141 }
142 
143 int main()
144 {
145     while ( ~scanf( "%d%d", &N, &Q ) )
146     {
147         build( 1, N, 1 );
148         blocks.clear();
149         while ( Q-- )
150         {
151             char oper[10];
152             int a, idx;
153             scanf( "%s", oper );
154             if ( oper[0] == 'R' )
155             {
156                 Update( 1, N, 0, 1, N, 1 );
157                 blocks.clear();
158                 puts("Reset Now");
159             }
160             else
161             {
162                 scanf( "%d", &a );
163                 switch( oper[0] )
164                 {
165                     case 'N':
166                     if ( len[1] < a ) puts("Reject New");
167                     else
168                     {
169                         int st = Query( a, 0, 1, N, 1 );
170                         printf( "New at %d\n", st );
171                         idx = BiSearch( st );
172                         blocks.insert( blocks.begin() + idx, node( st, st + a - 1 ) );
173                         Update( st, st + a - 1, 1, 1, N, 1 );
174                     }
175                     break;
176 
177                     case 'F':
178                     idx = BiSearch(a) - 1;
179                     if ( idx == -1 || a > blocks[idx].ed ) puts("Reject Free");
180                     else
181                     {
182                         printf( "Free from %d to %d\n", blocks[idx].st, blocks[idx].ed );
183                         Update( blocks[idx].st, blocks[idx].ed, 0, 1, N, 1 );
184                         blocks.erase( blocks.begin() + idx, blocks.begin() + idx + 1 );
185                     }
186                     break;
187 
188                     case 'G':
189                     --a;
190                     if ( a >= (int)blocks.size() ) puts("Reject Get");
191                     else printf( "Get at %d\n", blocks[a].st );
192                     break;
193                 }
194             }
195         }
196         puts("");
197     }
198     return 0;
199 }
原文地址:https://www.cnblogs.com/GBRgbr/p/3091867.html