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);
			}
		}
}



發佈了41 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章