mm.cpp/c/pas

题目简述:

时间限制: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 10
New 2
New 5
New 2
New 2
Free 3
Get 1
Get 2
Get 3
Free 3
Reset
输出样例
New at 1
Reject 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);
			}
		}
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值