poj3667 Hotel

来源:互联网 发布:炉石传说竞技场大数据 编辑:程序博客网 时间:2024/06/08 14:19

Description

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 (1 ≤ N ≤ 50,000) 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 Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of rto 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 Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

Input

* 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 D(b) Three space-separated integers representing a check-out: 2, Xi, and Di

Output

* 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.

Sample Input

10 61 31 31 31 32 5 51 6

Sample Output

1470

5

看了别人的思路自己写出来了,感觉真棒!(笑)

这道题属于线段树区间更新,首先维护线段树6个变量l,r,llen,rlen,tlen,mark(l,r表示区间最左和最右的坐标,llen表示从区间的最左端开始向右连续有空位的总个数,rlen表示从区间的最右端开始向左连续有空位的总个数,tlen表示这个区间最大连续空位的个数,mark表示这段区间是否有空位的情况,1表示都占满了,0表示都是空位,-1表示既有空位又有被占的。这里为了提高线段树的时间效率采用了成段更新,即每次不更新到叶节点,当b[i].l==l && b[i].r==r时返回。

每段的tlen:是左右子区间的tlen以及左子树rlen加上右子树llen的最大值。

每段的rlen:是左子树的rlen,如果左子树都是空位,那么再加上右子树llen.

每段的llen:是右子树的llen,如果右子树都是空位,那么再加上左子树llen.

#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<map>#include<queue>#include<stack>#include<string>using namespace std;#define maxn 50006int a[maxn];struct node{int l,r,llen,rlen,tlen,mark;}b[4*maxn];void build(int l,int r,int i){int mid;b[i].l=l;b[i].r=r;b[i].mark=0;b[i].llen=b[i].rlen=b[i].tlen=r-l+1;if(l==r) return;mid=(l+r)/2;build(l,mid,i*2);build(mid+1,r,i*2+1);}void update(int l,int r,int mark,int i){int mid;if(b[i].mark==mark)return;if(b[i].l==l && b[i].r==r){b[i].mark=mark;if(mark==0)b[i].llen=b[i].rlen=b[i].tlen=r-l+1;else b[i].llen=b[i].rlen=b[i].tlen=0;return;}if(b[i].mark!=-1){b[i*2].mark=b[i*2+1].mark=b[i].mark;if(b[i].mark==0){b[i*2].llen=b[i*2].rlen=b[i*2].tlen=b[i*2].r-b[i*2].l+1;b[i*2+1].llen=b[i*2+1].rlen=b[i*2+1].tlen=b[i*2+1].r-b[i*2+1].l+1;}else if(b[i].mark==1){b[i*2].llen=b[i*2].rlen=b[i*2].tlen=0;b[i*2+1].llen=b[i*2+1].rlen=b[i*2+1].tlen=0;}b[i].mark=-1;}mid=(b[i].l+b[i].r)/2;if(r<=mid)update(l,r,mark,i*2);else if(l>mid)update(l,r,mark,i*2+1);else{update(l,mid,mark,i*2);update(mid+1,r,mark,i*2+1);}int temp=max(b[i*2].tlen,b[i*2+1].tlen);b[i].tlen=max(temp,b[i*2].rlen+b[i*2+1].llen);b[i].llen=b[i*2].llen;if(b[i*2].llen==b[i*2].r-b[i*2].l+1) b[i].llen+=b[i*2+1].llen;b[i].rlen=b[i*2+1].rlen;if(b[i*2+1].rlen==b[i*2+1].r-b[i*2+1].l+1) b[i].rlen+=b[i*2].rlen;}int question(int num,int i){int mid;if(b[i].tlen<num)return 0;if(b[i].l==b[i].r && num==1)return b[i].l;if(b[i].mark!=-1){b[i*2].mark=b[i*2+1].mark=b[i].mark;if(b[i].mark==0){b[i*2].llen=b[i*2].rlen=b[i*2].tlen=b[i*2].r-b[i*2].l+1;b[i*2+1].llen=b[i*2+1].rlen=b[i*2+1].tlen=b[i*2+1].r-b[i*2+1].l+1;}else if(b[i].mark==1){b[i*2].llen=b[i*2].rlen=b[i*2].tlen=0;b[i*2+1].llen=b[i*2+1].rlen=b[i*2+1].tlen=0;}}if(b[i].llen>=num)return b[i].l;else if(b[i*2].tlen>=num) return question(num,i*2);else if(b[i*2].rlen+b[i*2+1].llen>=num)return b[i*2].r-b[i*2].rlen+1;else return question(num,i*2+1);}int main(){int n,m,i,j,a,b,c,ans;while(scanf("%d%d",&n,&m)!=EOF){build(1,n,1);for(i=1;i<=m;i++){scanf("%d",&a);if(a==1){scanf("%d",&b);ans=question(b,1);printf("%d\n",ans);if(ans)update(ans,ans+b-1,1,1);}else{scanf("%d%d",&b,&c);update(b,b+c-1,0,1);}}}return 0;}


1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 做生意的办房贷没有薪资流水怎么办 澳洲医保卡丢了怎么办 澳洲爱他美上火怎么办 学信网学籍在籍没交学费怎么办 宝宝从床上摔下来怎么办 狗没打针被咬了怎么办 狗咬了没破皮没出血怎么办 被宠物狗咬了出血了怎么办 让狗咬了下红了怎么办 狗牙齿碰到红了怎么办 加拿大学生签背景调查了怎么办 gpa不到3该怎么办英国 内地学生赴港签证怎么办 学生去日本旅游签证怎么办 澳洲未婚妻签需要单身证明怎么办 高院收到申诉材料怎么办? 辞职出国留学后社保怎么办 高三数学40来分怎么办 论文查重表格内容重复怎么办 榕树叶子掉光了怎么办 2017江苏高考2c怎么办 高考刚过三本线怎么办 江苏高考选修有d怎么办 西安地铁卡丢了怎么办 酒后头痛怎么办快速缓解疼痛 孕妇感冒头痛怎么办快速缓解疼痛 投稿后发现文章有错误怎么办 如有一方不同意离婚怎么办 孩子上课时注意力不集中怎么办 幼儿上课时注意力不集中怎么办 孩子读初中不爱读书怎么办 老师需要刺激孩子家长怎么办 错觉视界第11关怎么办 爱逃学的学生老师怎么办 论文投稿发现有错误怎么办 孩子上初中数学物理不好怎么办 火山小视频误踢怎么办 铁棍山药弄到手很痒怎么办 山药皮过敏很痒怎么办 貔貅被家人摸了怎么办? 摸了山药很痒怎么办