列表

详情


NC51140. Hotel

描述

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).
The cows and other visitors arrive in groups of size and approach the front desk to check in. Each group i requests a set of D_i contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.
Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms . Some (or all) of those rooms might be empty before the checkout.
Your job is to assist Canmuu by processing M checkin/checkout requests. The hotel is initially unoccupied.

输入描述

* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and Di (b) Three space-separated integers representing a check-out: 2, X_i, and D_i

输出描述

* Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

示例1

输入:

10 6
1 3
1 3
1 3
1 3
2 5 5
1 6

输出:

1
4
7
0
5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 61ms, 内存消耗: 4584K, 提交时间: 2020-04-24 00:26:57

/*
	题目大意:
	n个房间,初始为空 
	m次询问,2种类型
	1 d 要连续分配d个房间,给出满足条件的最小起始编号 ,如果不能满足输出0 
	2 x d 退房,从x开始连续退掉d个房间,房间原来可能是空的 
	
	需要维护最大0区间 ,类似维护最大连续子段和的思路 
*/ 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
struct SegmentTree{
	ll l,r,sum,tag;//l是紧靠左边的最大零区间的长度,r是紧靠右边的最大零区间的长度,sum最大零区间的长度,tag延迟标记 ,记录取反的次数 
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define sum(x) tree[x].sum
	#define tag(x) tree[x].tag
}tree[50010*4];
ll n,m,x,d,f;
void push_up(int p,int l,int r)
{
	int mid=(l+r)/2;
	l(p)=(l(p*2)==mid-l+1)?l(p*2)+l(p*2+1):l(p*2);//如果左子节点紧靠左边的最大零区间的长度是节点全部,那么该节点的紧靠左边的最大零区间长度就是l(p*2)+l(p*2+1) 
	r(p)=(r(p*2+1)==r-mid)?r(p*2+1)+r(p*2):r(p*2+1);
	sum(p)=max(max(sum(p*2),sum(p*2+1)),r(p*2)+l(p*2+1)); 
}
void push_down(int p,int l,int r)//向下传递标记
{
	if(tag(p)==1)
	{
		tag(p*2)=tag(p*2+1)=1;
		l(p*2)=r(p*2)=sum(p*2)=0;
		l(p*2+1)=r(p*2+1)=sum(p*2+1)=0;
	}
	if(tag(p)==2)
	{
		tag(p*2)=tag(p*2+1)=2;
		int mid=(l+r)/2;
		l(p*2)=r(p*2)=sum(p*2)=mid-l+1;
		l(p*2+1)=r(p*2+1)=sum(p*2+1)=r-mid;
	}
	tag(p)=0;
} 
void build(int p,int l,int r)
{
	if(l==r){l(p)=r(p)=sum(p)=1;return ;} //叶子节点
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	push_up(p,l,r);
}
void change(int p,int L,int R,int l,int r,int v)
{
	if(L<=l and r<=R)
	{
		if(v==1)//check in 
		{
			tag(p)=1;
			l(p)=r(p)=sum(p)=0;
		}
		else//check out 
		{
			tag(p)=2;
			l(p)=r(p)=sum(p)=r-l+1;
		}
		return ;
	}
	push_down(p,l,r);
	int mid=(l+r)/2;
	if(L<=mid)change(p*2,L,R,l,mid,v);
	if(mid<R)change(p*2+1,L,R,mid+1,r,v);
	push_up(p,l,r);
}
int ask(int p,int l,int r,int sum)
{
	if(l==r)return l;
	push_down(p,l,r);
	int mid=(l+r)/2;
	if(sum(p*2)>=sum)return ask(p*2,l,mid,sum);//在左边找
	else if(r(p*2)+l(p*2+1)>=sum)return mid-r(p*2)+1;
	else return ask(p*2+1,mid+1,r,sum); 
}
int main()
{
	scanf("%ld%ld",&n,&m);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		scanf("%ld",&f);
		if(f==1)
		{
			scanf("%ld",&d);
			if(sum(1)<d)puts("0");
			else
			{
				int pos=ask(1,1,n,d);
				change(1,pos,pos+d-1,1,n,1);
				printf("%d\n",pos);
			}
		}
		else
		{
			scanf("%ld%ld",&x,&d);
			change(1,x,x+d-1,1,n,2);	
		}
	}
} 

C++(g++ 7.5.0) 解法, 执行用时: 48ms, 内存消耗: 3604K, 提交时间: 2022-08-09 10:16:37

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int sum,lsum,rsum;
	int left,right;
	int lazy;
}a[200100];
int n,m;
void update(int k)
{
	a[k].lsum=a[k<<1].lsum;
	a[k].rsum=a[k<<1|1].rsum;
	if(a[k<<1].sum==a[k<<1].right-a[k<<1].left+1)
        a[k].lsum+=a[k<<1|1].lsum;
	if(a[k<<1|1].sum==a[k<<1|1].right-a[k<<1|1].left+1)
        a[k].rsum+=a[k<<1].rsum;
	a[k].sum=max(a[k<<1].rsum+a[k<<1|1].lsum,max(a[k<<1].sum,a[k<<1|1].sum));
	return ;
}
void pushdown(int k)
{
	if(a[k].lazy==-1) return;
	a[k<<1].lsum=a[k<<1].rsum=a[k<<1].sum=(a[k<<1].right-a[k<<1].left+1)*a[k].lazy;
	a[k<<1|1].lsum=a[k<<1|1].rsum=a[k<<1|1].sum=(a[k<<1|1].right-a[k<<1|1].left+1)*a[k].lazy;
	a[k<<1|1].lazy=a[k<<1].lazy=a[k].lazy;
	a[k].lazy=-1;
	return ;
}
void build(int k,int left,int right)
{
	a[k].left=left,a[k].right=right;
	a[k].lsum=a[k].rsum=a[k].sum=right-left+1;
    a[k].lazy=-1;
	if(left==right) return ;
	int mid=(left+right)>>1;
	build(k<<1,left,mid);
	build(k<<1|1,mid+1,right);
	return ;
}
void change(int k,int left,int right,int x)
{
	if(left<=a[k].left&&a[k].right<=right)
	{
		a[k].lazy=x;
		a[k].sum=a[k].lsum=a[k].rsum=(a[k].right-a[k].left+1)*x;
		return ;
	}
	pushdown(k);
	int mid=(a[k].left+a[k].right)>>1;
	if(left<=mid) change(k<<1,left,right,x);
	if(mid<right) change(k<<1|1,left,right,x);
	update(k);
	return ;
}
int query(int k,int x)
{
	if(a[k].left==a[k].right) return a[k].left;
	pushdown(k);
	if(a[k<<1].sum>=x) return query(k<<1,x);
	else if(a[k<<1].rsum+a[k<<1|1].lsum>=x) return a[k<<1].right-a[k<<1].rsum+1;
	else return query(k<<1|1,x);
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		build(1,1,n);
		while(m--)
		{
			int c;
			scanf("%d",&c);
			if(c==1)
			{
				int x;
				scanf("%d",&x);
				if(x>a[1].sum) printf("0\n");
				else
				{
					int ans=query(1,x);
					printf("%d\n",ans);
					change(1,ans,ans+x-1,0);
				}
			}
			else
			{
				int x,y;
				scanf("%d%d",&x,&y);
				change(1,x,x+y-1,1);
			}
		}
	}
	return 0;
}

C++ 解法, 执行用时: 167ms, 内存消耗: 3064K, 提交时间: 2022-05-02 09:50:41

#include<bits/stdc++.h>
using namespace std;
int n,m,x,l,op;
struct node{
	int ss,lm,rm,ll,len;
	#define mid (l+r>>1)
	#define lss (rt<<1)
	#define rss (rt<<1|1)
	#define ss(rt) te[rt].ss
	#define lm(rt) te[rt].lm
	#define rm(rt) te[rt].rm
	#define ll(rt) te[rt].ll
	#define len(rt) te[rt].len
}te[2000001];
void pu(int rt){
	lm(rt)=(lm(lss)==len(lss))?len(lss)+lm(rss):lm(lss);
	rm(rt)=(rm(rss)==len(rss))?len(rss)+rm(lss):rm(rss);
	ss(rt)=max(rm(lss)+lm(rss),max(ss(lss),ss(rss)));
}
void pd(int rt){
	if(!ll(rt))return;
	ll(lss)=ll(rss)=ll(rt);
	ss(lss)=lm(lss)=rm(lss)=(ll(rt)==1)?len(lss):0;
	ss(rss)=lm(rss)=rm(rss)=(ll(rt)==1)?len(rss):0;
	ll(rt)=0;
}
void bd(int l,int r,int rt){ss(rt)=lm(rt)=rm(rt)=len(rt)=r-l+1;if(l==r)return;bd(l,mid,lss);bd(mid+1,r,rss);}
void update(int L,int R,int tag,int l,int r,int rt){
	if(L<=l&&r<=R){ss(rt)=lm(rt)=rm(rt)=(tag==1)?len(rt):0;ll(rt)=tag;return;}
	pd(rt);
	if(L<=mid)update(L,R,tag,l,mid,lss);
	if(R>mid)update(L,R,tag,mid+1,r,rss);
	pu(rt);
}
int qr(int len,int l,int r,int rt){
	if(l==r)return l;
	pd(rt);
	if(ss(lss)>=len)return qr(len,l,mid,lss);
	if(rm(lss)+lm(rss)>=len)return mid-rm(lss)+1;
	return qr(len,mid+1,r,rss);
}
int main(){
	cin>>n>>m;
	bd(1,n,1);
	while(m--){
		cin>>op;
		if(op==1){
			cin>>x;
			if(ss(1)>=x)l=qr(x,1,n,1),cout<<l<<"\n",update(l,l+x-1,2,1,n,1);
			else cout<<"0\n";
		}
		else cin>>l>>x,update(l,l+x-1,1,1,n,1);
	}
	return 0;
}

上一题