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 (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 ≤ XiN-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 Di (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

题意:有一个旅店,刚开始有一段连续的房间,有两种操作,1、预定房间,找最靠前的一段连续D个房间(如果存在的话);2、退订房间,将[x,x+D-1]区间的房间退订。 解析:线段树维护,每个节点维护以下几个信息:左、右端点(le,ri),区间长度(len),从左边开始的最大连续长度(lelen),从右边开始的最大长度(rilen),该区间内最大连续长度(maxlen)。是否被预定用1和0表示。每次pushup(更新)时,更新
lelen,rilen,maxlen.首先lelen=lson.lelen(左儿子的),如果lelen==lson.len,说明可以向右扩展,那么lelen+=rson.lelen;rilen同理更新,maxlen=max{lson.maxlen,rson.maxlen,lelen,rilen,lson.rilen+rson.lelen};
有了这些信息,就很好去查找答案。 代码如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=;
const double eps=0.00000001;
const int maxn=;
int N,M;
struct node
{
int le,ri,len;
int maxlen,lelen,rilen; //区间最大长度,左边最大长度,右边最大长度
void init(int state) //根据是否被标记更新
{
maxlen=state*len;
lelen=rilen=maxlen;
}
}tree[*maxn];
void build_tree(int le,int ri,int id) //初始化
{
tree[id].le=le,tree[id].ri=ri;
tree[id].len=ri-le+;
tree[id].init();
if(le==ri) return;
int mid=(le+ri)/;
build_tree(le,mid,id*);
build_tree(mid+,ri,id*+);
return;
}
void pushdown(int id)
{
node& t=tree[id];
if(t.maxlen==t.len||t.maxlen==) //全被预定或是全未预定
{
int state=(t.maxlen==t.len);
tree[id*].init(state);
tree[id*+].init(state);
}
}
void pushup(int id)
{
node& fa=tree[id]; //父亲
node& lson=tree[id*]; //左儿子
node& rson=tree[id*+]; //右儿子
fa.lelen=lson.lelen;
if(fa.lelen==lson.len) fa.lelen+=rson.lelen; //可扩展
fa.rilen=rson.rilen;
if(fa.rilen==rson.len) fa.rilen+=lson.rilen;
fa.maxlen=max(lson.maxlen,rson.maxlen); //更新maxlen
fa.maxlen=max(fa.maxlen,max(fa.lelen,fa.rilen));
fa.maxlen=max(fa.maxlen,lson.rilen+rson.lelen);
}
int query(int id,int need)
{
if(tree[id].maxlen<need) return ; //无解
if(tree[id].lelen>=need) return tree[id].le; //最左边可行
if(tree[id*].maxlen>=need) return query(id*,need); //往左边找
if(tree[id*].rilen+tree[id*+].lelen>=need) return tree[id*].ri-tree[id*].rilen+; //中间
return query(id*+,need); //右边
}
void update(int x,int y,int id,int state)
{
int le=tree[id].le,ri=tree[id].ri;
if(x<=le&&ri<=y){ tree[id].init(state); return; }
pushdown(id);
int mid=(le+ri)/;
if(x<=mid) update(x,y,id*,state);
if(y>mid) update(x,y,id*+,state);
pushup(id);
}
void solve1()
{
int start;
scanf("%d",&start);
int ans=query(,start);
printf("%d\n",ans);
if(ans) update(ans,ans+start-,,); //找到才更新
}
void solve2()
{
int start,skip;
scanf("%d%d",&start,&skip);
update(start,start+skip-,,);
}
int main()
{
cin>>N>>M;
build_tree(,N,);
for(int i=;i<=M;i++)
{
int type;
scanf("%d",&type);
if(type==) solve1();
else solve2();
}
return ;
}

PKU 3667 Hotel(线段树)的更多相关文章

  1. poj 3667 Hotel (线段树)

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

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

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

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

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

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

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

  5. [USACO08FEB]酒店Hotel 线段树

    [USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...

  6. Hotel(线段树合并)

    Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 14958   Accepted: 6450 Descriptio ...

  7. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  8. POJ 1823 Hotel 线段树

    题目链接 线段树的区间合并. 和上一题差不多....第三种操作只需要输出maxx[1]的值就可以. #include <iostream> #include <vector> ...

  9. poj Hotel 线段树

    经典线段树的题. 每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度. 由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小: 1.如果当 ...

随机推荐

  1. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅰ

    3.1符号表 符号表最主要的目的就是将一个键和一个值联系起来.用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键值姐找到对应的值.要实现符号表,我们首先要定义其背后的数据结构, ...

  2. 【转载】视频编码(H264概述)

    一视频编码介绍 1.1 视频压缩编码的目标 1)保证压缩比例 2)保证恢复的质量 3)易实现,低成本,可靠性 1.2 压缩的出发点(可行性) 1)时间相关性 在一组视频序列中,相邻相邻两帧只有极少的不 ...

  3. hdu 5428 The Factor(数学)

    Problem Description There is a sequence of n positive integers. Fancycoder is addicted to learn thei ...

  4. 第六百二十一天 how can I 坚持

    好歹都是一些集成的框架,也懒得去深入研究了,微信小程序,今天体验了一个,虽然内心非常相信张小龙,但是还是不太看好,但是感觉确实需要一种方式去简化应用程序的开发,今天把没用的app都删了,太耽误时间了, ...

  5. Promise 异步执行的同步操作

    Promise 是用来执行异步操作的. 但有时一个异步操作需要等其他的异步操作完成,这时候就可以使用then来做. function loadImageAsync(url) { return new ...

  6. Spark MLlib Deep Learning Deep Belief Network (深度学习-深度信念网络)2.3

    Spark MLlib Deep Learning Deep Belief Network (深度学习-深度信念网络)2.3 http://blog.csdn.net/sunbow0 第二章Deep ...

  7. [HeadFrist-HTMLCSS学习笔记][第一章Web语言:开始了解HTML]

    head title body 元素= 开始标记 + 内容 +结束标记 还能给段落一个变量名 <p id="houseblend"> body </p> s ...

  8. sql service重置自动增长字段数字的方法

    1.--SQL表重置自增长字段(不删除表的数据) DBCC CHECKIDENT('表名', RESEED, 起始数) 2.--删除表数据的同时,重置自动增长字段 truncate table 表名

  9. .net DataTable 正确排序姿势

    关于dataTable中根据列排序正确姿势做个随笔,方便查阅 System.Data.DataTable dt = new System.Data.DataTable(); dt.Columns.Ad ...

  10. javascript,css3加载动画

    html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <me ...