Hotel
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 13124   Accepted: 5664

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 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 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 6
1 3
1 3
1 3
1 3
2 5 5
1 6

Sample Output

1
4
7
0
5 题目大意:游客要住旅馆,旅馆共有房间n间编号1-n,有m次询问,如果第一个数字为1,第二个数字为a表示问有没有连续的a间房,如果有,输出这a间房的第一间房编号,如果没有输出0。如果第一个数字为2,第二、三个数字分别为a,b则表示其他游客退房,将从a起的连续b间房退掉。 解题思路:用三个数组分别记录结点左端点起连续的区间长度,结点右端点起连续的区间长度及结点包含的最长的连续区间长度。cover表示各个结点当前的状态。
/*
线段树区间合并:query操作实现查询一段连续区间的左端点
update操作实现更新某段区间
PushUP操作实现合并左右儿子的区间
PushDown操作实现延迟标记向儿子下移
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=60000;
//分别记录结点左端、右端及结点表示的连续区间长度
int l_sum[maxn*4],r_sum[maxn*4],rt_sum[maxn*4];
int cover[maxn*4];//标记结点状态,空、满、初始值
void build(int rt,int L,int R){
l_sum[rt]=r_sum[rt]=rt_sum[rt]=(R-L+1);
cover[rt]=-1;
if(L==R)
return;
build(lson);
build(rson);
}
void PushUP(int rt,int len){
l_sum[rt]=l_sum[rt*2];
r_sum[rt]=r_sum[rt*2+1];
if(l_sum[rt]==len-(len/2)){
//如果左儿子左端连续区间长度为左儿子结点管辖长度,则说明该结点左端连续区间可以扩增,继续加上右儿子的从左端连续的区间
l_sum[rt]+=l_sum[rt*2+1];
}
if(r_sum[rt]==len/2){
//如果右儿子右端连续区间长度为右儿子结点管辖长度,则说明该结点右端连续区间长度可以扩增,继续加上左儿子从右端连续的区间
r_sum[rt]+=r_sum[rt*2];
}
//用左右儿子区间长度的最大值或合并后的最大值来更新该结点的区间长度
rt_sum[rt]=max(max(rt_sum[rt*2],rt_sum[rt*2+1]),r_sum[rt*2]+l_sum[rt*2+1]);
}
void Pushdown(int rt,int len){
if(cover[rt]!=-1){
cover[rt*2]=cover[rt*2+1]=cover[rt];
l_sum[rt*2]=r_sum[rt*2]=rt_sum[rt*2]=cover[rt]?0:len-len/2;
l_sum[rt*2+1]=r_sum[rt*2+1]=rt_sum[rt*2+1]=cover[rt]?0:len/2;
cover[rt]=-1;
}
}
void update(int rt,int L,int R,int flg,int l_ran,int r_ran){
if(l_ran<=L&&R<=r_ran){ //该结点在询问区间内
l_sum[rt]=r_sum[rt]=rt_sum[rt]= flg?0:R-L+1;
cover[rt]=flg;
return ;
}
Pushdown(rt,R-L+1); //延迟标记下移
if(l_ran<=mid){
update(lson,flg,l_ran,r_ran);
}
if(r_ran>mid){
update(rson,flg,l_ran,r_ran);
}
PushUP(rt,R-L+1); //合并出可以更长的连续区间
}
int query(int rt,int L,int R,int sum){
if(L==R){
return L; //返回满足条件的区间最左端点
}
Pushdown(rt,R-L+1); //延迟标记向下移动
if(rt_sum[rt*2]>=sum){
return query(lson,sum); //左儿子的最长区间长度能满足要求
}
if(r_sum[rt*2]+l_sum[rt*2+1]>=sum){
//左儿子的右端连续区间长度加右儿子的左端连续区间长度能满足要求
return mid-r_sum[rt*2]+1;
}
return query(rson,sum); //询问右儿子
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
build(1,1,n);
for(int i=0;i<m;i++){
int type,st,num;
scanf("%d",&type);
if(type==1){
scanf("%d",&num);
if(rt_sum[1]<num){
printf("0\n");
continue;
}
st=query(1,1,n,num);
printf("%d\n",st);
update(1,1,n,1,st,st+num-1);
}else{
scanf("%d%d",&st,&num);
update(1,1,n,0,st,st+num-1);
}
}
}
return 0;
}

  

												

Poj 3667——hotel——————【线段树区间合并】的更多相关文章

  1. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  2. POJ 3667 Hotel (线段树区间合并)

    题目链接:http://poj.org/problem?id=3667 最初给你n间空房,m个操作: 操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间. 操作2 a b ...

  3. POJ 3667 & 1823 Hotel (线段树区间合并)

    两个题目都是用同一个模板,询问最长的连续未覆盖的区间 . lazy代表是否有人,msum代表区间内最大的连续长度,lsum是从左结点往右的连续长度,rsum是从右结点往左的连续长度. 区间合并很恶心啊 ...

  4. poj 3667 Hotel (线段树)

    http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 94 ...

  5. poj 3667 Hotel(线段树,区间合并)

    Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...

  6. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  7. poj3667 Hotel (线段树 区间合并)

    poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...

  8. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  9. POJ 2482 Stars in Your Window (线段树区间合并+扫描线)

    这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)...但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用)  题意就是在平面上给你一些星 ...

随机推荐

  1. C语言/C++编程学习三种循环用法和区别

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  2. MVC 异常过滤

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  3. kali linux之DNS,NTP放大攻击

    DNS放大: 产生大流量的攻击方法-----单机的带宽优势,巨大的单机数量形成的流量汇聚,利用协议特性实现放大效果的流量 DNS协议放大效果----查询请求流量小,但响应流量可能非常巨大(dig AN ...

  4. 如果plsql连接没问题,但程序中报ORA-12504的错误

    说明程序中配置数据库连接的地方没有写tnsnames.ora中的SERVICE_NAME,或者SERVICE_NAME写的有错,检查一下,改正应该就好了

  5. C# Winform下一个热插拔的MIS/MRP/ERP框架12(数据处理基类)

    作为ERP等数据应用程序,数据库的处理是重中之重. 在框架中,我封装了一个数据库的基类,在每个模组启动或窗体启动过程中,实例化一个基类即可调用CRUD操作(create 添加read读取 update ...

  6. luoguP1401 城市

    https://www.luogu.org/problemnew/show/P1401 二分答案网络流判断是否可行即可 #include <bits/stdc++.h> using nam ...

  7. 洛谷P3254 圆桌问题(最大流)

    传送门 一道良心啊……没那么多麻烦了…… 从$S$向所有单位连边,容量为单位人数,从所有桌子向$T$连边,容量为桌子能坐的人数,从每一个单位向所有桌子连边,容量为$1$,然后跑一个最大流,看一看$S$ ...

  8. 洛谷P1963 [NOI2009]变换序列(二分图)

    传送门 我可能真的只会网络流……二分图的题一点都做不来…… 首先每个位置有两种取值,所以建一个二分图,只要有完美匹配就说明有解 考虑一下每一个位置,分别让它选择两种取值,如果都不能形成完美匹配,说明无 ...

  9. ubuntu 上的python不能解析jpeg,png?

    在安装pillow之前需要先安装以下支持包1.apt-get install libjpeg-dev libfreetype6-dev zlib1g-dev libpng12-dev2.安装pillo ...

  10. C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析

    看到这篇文章的题目,估计很多人都会问,这个组件是不是有些显的无聊了,说到web通信,很多人都会想到ASP.NET SignalR,或者Nodejs等等,实现web的网络实时通讯.有关于web实时通信的 ...