The question indicates that the given memory is fast, and the correct answer should be output according to the command.
New X indicates the first address of the blank memory whose request length is X. If the output reject new
Free x releases the memory block containing x nodes. Note that the memory block is a region determined by the new operation, that is, it is not necessary to regard the physically adjacent memory block as a memory block.
Get X to get the X-th memory block from left to right.
Reset reset Interval
To meet these requirements, set a line segment tree. Each node retains the Left and Right consecutive blank segments and the total length of the segments. In this way, the new command can be processed, while the free and get commands are retained by vector and optimized by binary search.
The Code is as follows:
View code
# Include <cstdio>
# Include <cstring>
# Include <cstdio>
# Include <algorithm>
# Include <vector>
# Define maxn50000
Using namespace STD;
Struct
{
Int L, R;
Int Lmax, rmax, Max, cover;
} Seg [maxn * 4];
Struct Node
{
Int S, E;
} Info;
Void up (int f)
{
SEG [f]. Lmax = seg [F <1]. Lmax;
SEG [f]. rmax = seg [F <1 | 1]. rmax;
If (SEG [F <1]. Cover = 0)
SEG [f]. Lmax + = seg [F <1 | 1]. Lmax;
If (SEG [F <1 | 1]. Cover = 0)
SEG [f]. rmax + = seg [F <1]. rmax;
SEG [f]. max = max (SEG [F <1]. Max, SEG [F <1 | 1]. max );
SEG [f]. max = max (SEG [f]. Max, SEG [F <1]. rmax + seg [F <1 | 1]. Lmax );
If (SEG [F <1]. Cover = seg [F <1 | 1]. Cover)
SEG [f]. Cover = seg [F <1]. cover;
Else
SEG [f]. Cover =-1;
}
Void build (int f, int L, int R)
{
Int mid = L + r> 1;
SEG [f]. L = L, SEG [f]. r = R;
SEG [f]. Lmax = seg [f]. rmax = seg [f]. max = r-L + 1;
SEG [f]. Cover = 0;
If (r> L)
{
Build (F <1, L, mid );
Build (F <1 | 1, Mid + 1, R );
}
}
Void modify (int f, int L, int R, int Val)
{
Int mid = seg [f]. L + seg [f]. r> 1;
If (SEG [f]. L = L & R = seg [f]. R)
{
SEG [f]. Cover = val;
If (val = 1) // If the command is occupied
SEG [f]. Lmax = seg [f]. rmax = seg [f]. max = 0;
Else
SEG [f]. Lmax = seg [f]. rmax = seg [f]. max = r-L + 1;
}
Else if (SEG [f]. r> seg [f]. l)
{
If (SEG [f]. Cover = 0)
{// The Lazy operation is equivalent to formatting a general downward update.
SEG [F <1]. Cover = seg [F <1 | 1]. Cover = 0;
SEG [F <1]. Lmax = seg [F <1]. R-seg [F <1]. L + 1;
SEG [F <1]. rmax = seg [F <1]. R-seg [F <1]. L + 1;
SEG [F <1]. max = seg [F <1]. R-seg [F <1]. L + 1;
SEG [F <1 | 1]. Lmax = seg [F <1 | 1]. R-seg [F <1 | 1]. L + 1;
SEG [F <1 | 1]. rmax = seg [F <1 | 1]. R-seg [F <1 | 1]. L + 1;
SEG [F <1 | 1]. max = seg [F <1 | 1]. R-seg [F <1 | 1]. L + 1;
SEG [f]. Cover =-1;
}
Else if (SEG [f]. Cover = 1)
{
SEG [F <1]. Cover = seg [F <1 | 1]. Cover = 1;
SEG [F <1]. Lmax = 0;
SEG [F <1]. rmax = 0;
SEG [F <1]. max = 0;
SEG [F <1 | 1]. Lmax = 0;
SEG [F <1 | 1]. rmax = 0;
SEG [F <1 | 1]. max = 0;
SEG [f]. Cover =-1;
}
If (r <= mid)
Modify (F <1, L, R, Val );
Else if (L> mid)
Modify (F <1 | 1, L, R, Val );
Else
{
Modify (F <1, L, mid, Val );
Modify (F <1 | 1, Mid + 1, R, Val );
}
Up (f );
}
}
Int query (int f, int size)
{
Int mid = seg [f]. L + seg [f]. r> 1;
If (SEG [f]. max <size)
Return 0;
Else if (SEG [f]. r> seg [f]. l)
{
If (SEG [f]. Lmax> = size)
{
Return seg [f]. L;
}
Else if (SEG [F <1]. max> = size)
Return query (F <1, size );
Else if (SEG [F <1]. rmax + seg [F <1 | 1]. Lmax> = size)
Return seg [F <1]. R-seg [F <1]. rmax + 1;
Else
Return query (F <1 | 1, size );
}
}
Int bsearch (INT POs, vector <node> & V, int way)
{
Int L = 0, r = V. Size ()-1;
While (L <= r)
{
Int mid = L + r> 1;
If (Pos> V [Mid]. s)
L = Mid + 1;
Else if (Pos <V [Mid]. s)
R = mid-1;
Else if (way = 1)
Return mid;
}
If (way = 0)
Return L;
Else
Return R;
}
Int main ()
{
Int n, m, X, Loc;
Char op [10];
While (scanf ("% d", & N, & M) = 2)
{
Build (1, 1, n );
Vector <node> V;
Vector <node >:: iterator it;
While (M --)
{
Scanf ("% s", OP );
If (OP [0] = 'R ')
{
SEG [1]. Lmax = seg [1]. rmax = seg [1]. max = N;
SEG [1]. Cover = 0;
V. Clear ();
Puts ("Reset now ");
}
Else if (OP [0] = 'n ')
{
Scanf ("% d", & X );
Int Pos = query (1, x );
If (Pos = 0)
Puts ("reject new ");
Else
{
Printf ("New at % d \ n", POS );
Modify (1, POs, POS + X-1, 1 );
It = V. Begin () + bsearch (Pos, V, 0 );
Info. S = POs, info. E = POS + X-1;
V. insert (it, Info );
}
}
Else if (OP [0] = 'F ')
{
Scanf ("% d", & X );
Loc = bsearch (x, V, 1 );
If (loc =-1)
Puts ("reject free ");
Else
{
It = V. Begin () + LOC;
If (x> = it-> S & x <= it-> E)
{
Printf ("free from % d to % d \ n", It-> S, IT-> E );
Modify (1, IT-> S, IT-> E, 0 );
V. Erase (it );
}
Else
Puts ("reject free ");
}
}
Else
{
Scanf ("% d", & X );
If (x> v. Size ())
Puts ("reject get ");
Else
Printf ("Get at % d \ n", V [x-1]. s );
}
}
Puts ("");
}
Return 0;
}