/* 分析本题和我前几天做的题目非常类似,但模拟过程需要用vector 来处理。。。貌似我又弱在了这个stl 身上了。。整了2个小时的stl......... 题目分析:题目有4个操作:Reset指清空整个线段树,即题目所说的清空整个内存块; New N就是申请N个最靠左边的连续内存块, Free x操作是释放包含x的连续内存块, Get x,就是获得第x个内存块的起始节点 我们用vector存取所有申请过的空间,删除所有释放的空间,查询第n个区间也是非常easy。 关键在于vector可以在中间进行查询,增减!!这也是该题所要求的一个一个知识点。 还是对stl 不熟 */ #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; const int maxn=55555; int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],col[maxn<<2],n,m; #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r char op[10]; struct node///优先队列 { int l,r; bool operator < (const node &cmp) const { return l<cmp.l; } } ; void pushup(int rt,int l,int r) { int mid=(l+r)>>1; lmax[rt]=lmax[rt<<1]; rmax[rt]=rmax[rt<<1|1]; mmax[rt]=max(rmax[rt<<1]+lmax[rt<<1|1],max(mmax[rt<<1],mmax[rt<<1|1])); if(lmax[rt<<1]==mid-l+1) lmax[rt]+=lmax[rt<<1|1]; if(rmax[rt<<1|1]==r-mid) rmax[rt]+=rmax[rt<<1]; } void build(int rt,int l,int r) { lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1); col[rt]=-1; if(l==r)return; int mid=(l+r)>>1; build(lson); build(rson); pushup(rt,l,r); } void pushdown(int rt,int l,int r) { if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=col[rt]; int mid=(l+r)>>1; if(col[rt]==1)///已被占用 { lmax[rt<<1]=rmax[rt<<1]=lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1]=mmax[rt<<1|1]=0; } else { lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=mid-l+1; lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=r-mid; } col[rt]=-1; } } void updata(int rt,int l,int r,int L,int R,int val) { if(L<=l&&r<=R) { col[rt]=val; lmax[rt]=rmax[rt]=mmax[rt]=(r-l+1)*(val^1); return ; } pushdown(rt,l,r); int mid=(l+r)>>1; if(mid>=L)updata(lson,L,R,val); if(mid<R)updata(rson,L,R,val); pushup(rt,l,r); } int query(int rt,int l,int r,int len) { if(mmax[rt]<len) return -1; if(lmax[rt]>=len)return l; pushdown(rt,l,r); int mid=(l+r)>>1; if(mmax[rt<<1]>=len)return query(lson,len); if(rmax[rt<<1]+lmax[rt<<1|1]>=len) return mid-rmax[rt<<1]+1; return query(rson,len); } int main() { int i,j,res,tmp; char s[10]; vector<node>V; while(scanf("%d %d",&n,&m)!=EOF) { build(1,1,n); V.clear(); while(m--) { scanf("%s",s); if(s[0] == 'N') { scanf("%d",&res); if(mmax[1] < res) puts("Reject New"); else { int ret= query(1,1,n,res); printf("New at %d\n",ret); updata(1,1,n,ret,ret+res-1,1); node p; p.l = ret; p.r = ret+res-1; vector<node>::iterator it; it = upper_bound(V.begin(),V.end(),p); V.insert(it,p); } } else if(s[0] == 'F') { scanf("%d",&res); node p; p.l = res; p.r = res; vector<node>::iterator it; it = upper_bound(V.begin(),V.end(),p); int tmp = it - V.begin() - 1; if(tmp == -1 || V[tmp].r<res) puts("Reject Free"); else { printf("Free from %d to %d\n", V[tmp].l, V[tmp].r); updata(1,1,n,V[tmp].l,V[tmp].r,0); V.erase(V.begin()+tmp); } } else if(s[0] == 'G') { scanf("%d",&res); if(res > V.size()) puts("Reject Get"); else printf("Get at %d\n",V[res-1].l); } else if(s[0] == 'R') { updata(1,1,n,1,n,0); V.clear(); puts("Reset Now"); } } printf("\n"); } return 0; } /* 6 16 New 2 New 5 New 2 New 2 Free 3 Get 1 Get 2 Get 3 Free 3 Reset New 2 New 5 New 2 New 2 */