题目简述:
时间限制:1s 内存限制:256MB
题目描述:
看了题目名称不要乱想,mm是MemoryManage的缩写。内存一共有N个单元,有M次内存操作。请你编写一个程序模拟内存的管理过程,有如下几个操作:
Reset:将所有在使用中的内存释放。
New x:申请新的一段长度为x的,没有被使用过的内存,如果有多段就找左端点地址最小的那段。
Free x:将第x个单元的内存所在的正在使用的那段内存释放。
Get x:询问把所有申请成功的,没有被释放的内存段左端点升序排序后,第x个左端点的值。
输入描述
第一行两个整数N,M。接下来M行里面,每行一个操作。
输出描述
共M行,对于Reset操作,输出"Reset Now"
对于New操作,如果成功,输出"New at A",其中A是头地址,否则输出"Reject New"
对于Free操作,如果该内存被释放,输出"Free from A to B",表示释放的区间,否则输出"Reject Free"
对于Get操作,如果找到了第x个内存符合题意的则输出"Get at A",其中A是头端点,否则输出"Reject Get"
输入样例
6 10New 2
New 5
New 2
New 2
Free 3
Get 1
Get 2
Get 3
Free 3
Reset
输出样例
New at 1Reject New
New at 3
New at 5
Free from 3 to 4
Get at 1
Get at 5
Reject Get
Reject Free
Reset Now
数据规模及约定
对于20%的数据,N,M<=1000。对于100%的数据,N,M<=50000。
很无聊。。就是数据结构。
我是用三颗线段树来维护,很蛋疼不说了。。
可以用两颗平衡树维护,一颗维护被占用的区间,一颗维护没有被占用的区间。
然后乱搞就可以了。(懒不想写。)
下面是很沙茶的线段树代码...
#include <cstdio>
#include <algorithm>
#define gt getchar()
int getx(){
char c;int x;bool pd=0;
for (c=gt;c!='-'&&(c<'0'||c>'9');c=gt);
if (c=='-') pd=true,c=gt;
for (x=0;c>='0'&&c<='9';c=gt)
x=(x<<3)+(x<<1)+c-'0';
return pd?-x:x;
}
int Max(const int &a,const int &b){return a>b?a:b;}
const int MAX_N=50050;
#define lcv v<<1
#define rcv v<<1|1
#define lc v<<1,l,mid
#define rc v<<1|1,mid+1,r
int n,m;
struct Node1{int v,k;};
namespace T1{
int k[MAX_N<<2];
bool reset[MAX_N<<2];
inline void down(int v){
if (reset[v]){
k[lcv]=0,k[rcv]=0;
reset[lcv]=reset[rcv]=1;
reset[v]=0;
}
}
inline void up(int v){
k[v]=Max(k[lcv],k[rcv]);
}
void modify(int v,int l,int r,int p,int x){
if (l==r){k[v]=x;return;}
down(v);
int mid=l+r>>1;
if (p<=mid) modify(lc,p,x);
else modify(rc,p,x);
up(v);
}
Node1 query(int v,int l,int r,int x){
if (l==r) return (Node1){l,k[v]};
down(v);//????
int mid=l+r>>1;
if (k[lcv]>=x) return query(lc,x);
else return query(rc,x);
up(v);//????
}
int query2(int v,int l,int r,int p){
if (l==r) return k[l];
down(v);
int mid=l+r>>1;
if (p<=mid) return query2(lc,p);
else return query2(rc,p);
up(v);
}
inline Node1 query(int x){
return (x>k[1])?(Node1){-1,-1}:query(1,1,n,x);
}
inline void Reset(){
k[1]=0,reset[1]=1;
modify(1,1,n,1,n);
}
}
struct Node2{int v;bool color;};
namespace T2{
Node2 k[MAX_N<<2];
bool isflag[MAX_N<<2];
inline void down(int v){
if (isflag[v]){
k[lcv]=k[rcv]=k[v];
isflag[lcv]=isflag[rcv]=1;
isflag[v]=0;
}
}
inline void modify(int v,int l,int r,int s,int t,const Node2 &x){
if (s<=l&&r<=t){k[v]=x;isflag[v]=true;return;}
down(v);
int mid=l+r>>1;
if (s<=mid) modify(lc,s,t,x);
if (t> mid) modify(rc,s,t,x);
}
inline Node2 query(int v,int l,int r,int p){
if (l==r) return k[v];
down(v);
int mid=l+r>>1;
if (p<=mid) return query(lc,p);
else return query(rc,p);
}
inline void Reset(){
modify(1,1,n,1,n,(Node2){1,0});
}
}
namespace T3{
int k[MAX_N<<2];
bool reset[MAX_N<<2];
inline void down(int v){
if (reset[v]){
k[lcv]=k[rcv]=0;
reset[lcv]=reset[rcv]=1;
reset[v]=0;
}
}
inline void up(int v){
k[v]=k[lcv]+k[rcv];
}
void modify(int v,int l,int r,int p,int x){
if (l==r){k[v]=x;return;}
down(v);
int mid=l+r>>1;
if (p<=mid) modify(lc,p,x);
else modify(rc,p,x);
up(v);
}
inline int query(int v,int l,int r,int x){
if (l==r) return l;
down(v);
int mid=l+r>>1;
if (k[lcv]>=x) return query(lc,x);
else return query(rc,x-k[lcv]);
up(v);
}
inline int query(int x){
return (x>k[1])?-1:query(1,1,n,x);
}
inline void Reset(){
k[1]=0;reset[1]=1;
}
}
int a[MAX_N];
char opt;
int A,Len;
Node1 tp1;Node2 tp2,Pre,Suf;
int main(){
freopen("mm.in","r",stdin);
freopen("mm.out","w",stdout);
n=getx(),m=getx();
T1::Reset(),T2::Reset(),T3::Reset();
// for (int i=1;i<=n;++i) printf("%d %d\n",T1::query(1,1,n,i).v,T1::query(1,1,n,i).k);
while (m--){
for (opt=gt;opt!='R'&&opt!='N'&&opt!='F'&&opt!='G';opt=gt);
if (opt=='R'){
printf("Reset Now\n");
T1::Reset(),T2::Reset(),T3::Reset();
a[1]=n;
}else
if (opt=='N'){
int x=getx();
tp1=T1::query(x);
if (tp1.v<0){printf("Reject New\n");continue;}
printf("New at %d\n",tp1.v);
T1::modify(1,1,n,tp1.v,0);
if (tp1.k>x){
T1::modify(1,1,n,tp1.v+x,tp1.k-x);
a[tp1.v+x]=tp1.k-x;
}
T2::modify(1,1,n,tp1.v,tp1.v+x-1,(Node2){tp1.v,1});
a[tp1.v]=x;
if (tp1.k>x)T2::modify(1,1,n,tp1.v+x,tp1.v+tp1.k-1,(Node2){tp1.v+x,0});
T3::modify(1,1,n,tp1.v,1);
// for (int i=1;i<=n;++i) printf("%d %d\n",T2::query(1,1,n,i).v,T2::query(1,1,n,i).color);
}else
if (opt=='F'){
int x=getx();
if (x<1||x>n){printf("Reject Free\n");continue;}
tp2=T2::query(1,1,n,x);
if (tp2.color==0){printf("Reject Free\n");continue;}
A=tp2.v;Len=a[tp2.v];
printf("Free from %d to %d\n",A,A+a[A]-1);
T3::modify(1,1,n,A,0);
if (A-1>0){
Pre=T2::query(1,1,n,A-1);
if (Pre.color==0){
Len+=A-Pre.v;
// printf("Pre %d %d\n",A,Pre.v);
A=Pre.v;
}
}
if (A+Len-1<n){
Suf=T2::query(1,1,n,A+Len);
// printf("%d %d %d\n",A+Len,Suf.v,Suf.color);
if (Suf.color==0){
// printf("Suf %d %d\n",A+Len,a[A]);
T1::modify(1,1,n,A+Len,0);
Len+=a[A+Len];
}
}
T1::modify(1,1,n,A,Len);
a[A]=Len;
T2::modify(1,1,n,A,A+Len-1,(Node2){A,0});
// printf("A %d LEN %d\n",A,Len);
// for (int i=1;i<=n;++i) printf("%d %d\n",T2::query(1,1,n,i).v,T2::query(1,1,n,i).color);
}else
if (opt=='G'){
int x=getx();
if (x<1||x>n){printf("Reject Get\n");continue;}
int A=T3::query(x);
if (A<0){printf("Reject Get\n");continue;}
printf("Get at %d\n",A);
}
}
}