bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)
1593: [Usaco2008 Feb]Hotel 旅馆
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 758 Solved: 419
[Submit][Status][Discuss]
Description
奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 贝茜一行,以及其他慕名而来的旅游者,都是一批批地来到旅馆的服务台,希望能订到D_i (1 <= D_i <= N)间连续的房间。服务台的接待工作也很简单:如果存在r满足编号为r..r+D_i-1的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字X_i、D_i 描述,表示编号为X_i..X_i+D_i-1 (1 <= X_i <= N-D_i+1)房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理M (1 <= M < 50,000)个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。
Input
* 第1行: 2个用空格隔开的整数:N、M
* 第2..M+1行: 第i+1描述了第i个请求,如果它是一个订房请求,则用2个数字 1、D_i描述,数字间用空格隔开;如果它是一个退房请求,用3 个以空格隔开的数字2、X_i、D_i描述
Output
* 第1..??行: 对于每个订房请求,输出1个独占1行的数字:如果请求能被满足 ,输出满足条件的最小的r;如果请求无法被满足,输出0
Sample Input
1 3
1 3
1 3
1 3
2 5 5
1 6
Sample Output
4
7
0
5
/* 求最长空序列 思路类似动态最大子段和 详见代码 */ #include<iostream> #include<cstdio>#define N 50010using namespace std; int n,m; struct tree {int l,r,m,lm,rm,sum,flag; }tr[N<<2];void build(int now,int l,int r) {tr[now].l=l;tr[now].r=r;tr[now].lm=tr[now].rm=tr[now].m=tr[now].sum=r-l+1;if(l==r) return;int mid=(l+r)>>1;build(now<<1,l,mid);build(now<<1|1,mid+1,r); }void pushup(int now) {if(tr[now<<1].sum==tr[now<<1].m) tr[now].lm=tr[now<<1].sum+tr[now<<1|1].lm;else tr[now].lm=tr[now<<1].lm;if(tr[now<<1|1].sum==tr[now<<1|1].m)tr[now].rm=tr[now<<1|1].sum+tr[now<<1].rm;else tr[now].rm=tr[now<<1|1].rm;tr[now].m=max(tr[now<<1].m,tr[now<<1|1].m);tr[now].m=max(tr[now].m,tr[now<<1].rm+tr[now<<1|1].lm); }void pushdown(int now) {int tag=tr[now].flag;tr[now].flag=0;if(tag==1){tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=tr[now<<1].sum;tr[now<<1|1].lm=tr[now<<1|1].rm=tr[now<<1|1].m=tr[now<<1|1].sum;tr[now<<1].flag=tr[now<<1|1].flag=1;}else if(tag==2){tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=0;tr[now<<1|1].lm=tr[now<<1|1].rm=tr[now<<1|1].m=0;tr[now<<1].flag=tr[now<<1|1].flag=2;} }void change(int now,int l,int r,int f) {if(tr[now].l==l && tr[now].r==r){if(f==1) tr[now].lm=tr[now].rm=tr[now].m=tr[now].sum;else tr[now].lm=tr[now].rm=tr[now].m=0;tr[now].flag=f;return;}if(tr[now].flag) pushdown(now);int mid=(tr[now].l+tr[now].r)>>1;if(r<=mid) change(now<<1,l,r,f);else if(l>mid) change(now<<1|1,l,r,f);else{change(now<<1,l,mid,f);change(now<<1|1,mid+1,r,f);}pushup(now); }int ask(int now,int x) {if(tr[now].flag) pushdown(now);int mid=(tr[now].l+tr[now].r)>>1;if(tr[now].l==tr[now].r) return tr[now].l;if(tr[now<<1].m>=x) return ask(now<<1,x);if(tr[now<<1].rm+tr[now<<1|1].lm>=x) return mid-tr[now<<1].rm+1;return ask(now<<1|1,x); }int main() {scanf("%d%d",&n,&m);build(1,1,n);for(int i=1;i<=m;i++){int f,x,y;scanf("%d",&f);if(f==1){scanf("%d",&x);if(tr[1].m<x) printf("0\n");else{int p=ask(1,x);printf("%d\n",p);change(1,p,p+x-1,2);}}else {scanf("%d%d",&x,&y);change(1,x,x+y-1,1);}}return 0; }
转载于:https://www.cnblogs.com/L-Memory/p/7246835.html
bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)相关推荐
- 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...
- 1593: [Usaco2008 Feb]Hotel 旅馆
1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 489 Solved: 272 [Subm ...
- POJ 3667 Hotel(线段树)
POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...
- B1230 [Usaco2008 Nov]lites 开关灯 线段树
就是线段树维护异或和.之前我线段树区间修改down都是修改当前区间,结果debug出不来,改成每次向下了. 题干: DescriptionFarmer John尝试通过和奶牛们玩益智玩具来保持他的奶牛 ...
- 【线段树区间合并】BZOJ1593-[Usaco2008 Feb]Hotel 旅馆
好无聊,以前写过没什么好讲的,水过.戳 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 ...
- 数据结构二之线段树Ⅰ——Count Color,Hotel,Transformation,Tree Generator™
普通的下标线段树 Count Color Hotel Transformation Tree Generator™ Count Color POJ2777 查询区间内颜色种类数,观察到颜色种类数只有3 ...
- 【转】poj 1823 hotel 线段树【Good】
题意:一个hotel,有n个连续的房间,开始时均无人住宿 共有3种操作 1 a b 从a开始连续b个房间全部旅客住宿 [a,a+b-1]; 2 a b 从a开始连续b个房间全部旅客离开 [a,a+b- ...
- HDU - 3667 Hotel(线段树+区间合并)
题目链接:点击查看 题目大意:给出n个连续的空房间,依次进行m个操作,操作一是查询操作,查询在总区间内的一段连续的长度为x的空房间,并 且该位置要靠左,如果查询到返回最左边的端点,并将其占用,找不到返 ...
- 线段树专辑——pku 3667 Hotel
http://poj.org/problem?id=3667 哈哈,经典中的经典题啊.利用线段树求最大连续空闲区间,并返回空闲区间的起点坐标. View Code 1 #include<iost ...
最新文章
- java实现https请求
- MSDynamicsAX2009成本处理与重估(中文)
- Linux 父进程 子进程 回收,回收 fork() 的子进程
- php 定时脚本执行wget无效_写了个Bug,误执行rm fr /*,瞬间背后一凉!
- leetcode 394. Decode String | 394. 字符串解码(用栈做表达式转换)
- 脉冲宽度调制pdm_STM32第七章-脉冲宽度调制
- 东莞市商业学校计算机平面设计在哪个校区,东莞市商业学校
- 都市异乡年轻人的艰难“房”事
- 《嵌入式Linux基础教程学习笔记一》
- Python如何对图片进行缩放,旋转,翻转,添加文字以及如何截取并粘贴图像到图片中
- QT视频采集之编码Enc和录像Rec
- tunel凋亡试剂盒说明书_TUNEL细胞凋亡试剂盒内容及操作步骤(精)
- 计算机登录网站慢手机快,手机WiFi网速慢,简单输入几个数字立马变快!
- Android 清理后台进程
- RTD温度测量系统的实现
- java 解决oracle US7ASCII编码,sql查询时
- 微信视频号直播功能上线;全面打通视频号+公众号+小商店+直播私域生态组合;丨国仁网络资讯
- SSH远程访问以及控制
- 使用离线语音夜灯联动控制家里其他灯具和电器
- Android 获取网络视频第一帧