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 }

你可能感兴趣的:(memory)