题目大意:
给你一段内存,现在有如下的几种操作
1:Reset,把内存全部释放
2:New x 申请一段内存,并输出内存的起始位置
3:Free X释放包含x在内的内存块,并输出它的起始位置和结束位置;
4:Get X得到第x个内存块的起始位置
解题思路:
对于申请和释放内存的时候,我们可以同过线段树的区间修改轻松的实现,对于边界信息虽然我们可以通过添加信息维护,但是统计第几个的时候,这个不易实现,网上有建立2棵线段树的做法,但过于繁琐,我们可以借助vector轻松的输出第X个内存块的的信息的时候,即区间的覆盖用线段树实现,再把区间信息存在vector中,进行申请和删除的时候同时处理线段树和vector;
upper_bound实现的是查找比第一个比元素x大的位置;
insert(x,y)是在x的位置前插入元素y
erase(x)是删除x位置的元素;
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 100010
#define L(a) (a)<<1
#define R(a) (a)<<1|1
struct Node{
int lc,rc;
int len;
int ls,rs,ms;
int cover;
}node[3*maxn];
struct Line{
int s,e;
};
vector<Line> q;
bool cmp(const Line &a,const Line &b)
{
return a.s<b.s;
}
void pushup(int k)
{
node[k].ls=node[L(k)].ls;
node[k].rs=node[R(k)].rs;
if(node[L(k)].ls==node[L(k)].len)
node[k].ls+=node[R(k)].ls;
if(node[R(k)].rs==node[R(k)].len)
node[k].rs+=node[L(k)].rs;
node[k].ms=max(max(node[L(k)].ms,node[R(k)].ms),node[L(k)].rs+node[R(k)].ls);
}
void pushdown(int k)
{
if(node[k].cover!=-1)
{
node[L(k)].cover=node[R(k)].cover=node[k].cover;
node[L(k)].ls=node[L(k)].rs=node[L(k)].ms=node[k].cover?0:node[L(k)].len;
node[R(k)].ls=node[R(k)].rs=node[R(k)].ms=node[k].cover?0:node[R(k)].len;
node[k].cover=-1;
}
}
void create(int k,int l,int r)
{
node[k].lc=l;
node[k].rc=r;
node[k].cover=-1;
node[k].len=r-l+1;
node[k].ls=node[k].rs=node[k].ms=r-l+1;
if(l==r)
return ;
int mid=(l+r)>>1;
create(L(k),l,mid);
create(R(k),mid+1,r);
}
void updata(int k,int l,int r,int op)
{
if(node[k].lc>=l&&node[k].rc<=r)
{
node[k].cover=op;
node[k].ls=node[k].rs=node[k].ms=op?0:node[k].len;
return ;
}
pushdown(k);
int mid=(node[k].lc+node[k].rc)>>1;
if(r<=mid)
updata(L(k),l,r,op);
else if(l>mid)
updata(R(k),l,r,op);
else
{
updata(L(k),l,mid,op);
updata(R(k),mid+1,r,op);
}
pushup(k);
}
int query(int k,int op)
{
if(node[k].lc==node[k].rc)
{
return node[k].lc;
}
pushdown(k);
int mid=(node[k].lc+node[k].rc)>>1;
if(node[L(k)].ms>=op)
return query(L(k),op);
else if(node[L(k)].rs+node[R(k)].ls>=op)
return mid-node[L(k)].rs+1;
else
return query(R(k),op);
}
int main()
{
int n,m;
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
create(1,1,n);
q.clear();
char s[10];
int op;
for(int i=0;i<m;i++)
{
scanf("%s",s);
if(s[0]=='N')
{
scanf("%d",&op);
if(op>node[1].ms)
printf("Reject New\n");
else
{
int tt=query(1,op);
printf("New at %d\n",tt);
Line line;
line.s=tt;
line.e=tt+op-1;
vector<Line>::iterator it;
it=upper_bound(q.begin(),q.end(),line,cmp);
q.insert(it,line);
updata(1,tt,tt+op-1,1);
}
}
else if(s[0]=='F')
{
scanf("%d",&op);
Line line;
line.s=line.e=op;
vector<Line>::iterator it;
it=upper_bound(q.begin(),q.end(),line,cmp);
int tt=it-q.begin()-1;
if(tt==-1||q[tt].e<op)
printf("Reject Free\n");
else
{
printf("Free from %d to %d\n",q[tt].s,q[tt].e);
updata(1,q[tt].s,q[tt].e,0);
q.erase(q.begin()+tt);
}
}
else if(s[0]=='G')
{
scanf("%d",&op);
if(op>q.size())
printf("Reject Get\n");
else
printf("Get at %d\n",q[op-1].s);
}
else
{
printf("Reset Now\n");
updata(1,1,n,0);
q.clear();
}
}
printf("\n");
}
}