http://poj.org/problem?id=3667

Hotel
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 9484   Accepted: 4066

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

Source

 
【题解】:
  线段树:
struct Nod
{
    int l,r;
    int ml,mm,mr;  //左边的空位,区间最大的空位,右边的空位
}node[N<<2];
查找的时候优先向左边查找插入;
注意各种状态的更新
详见代码
 
【code】:
 /**
judge status: Accepted exe.time:563MS
exe.memory 2712K language:C++
*/ #include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm> #define N 50010 #define lson p<<1
#define rson p<<1|1 using namespace std; struct Nod
{
int l,r;
int ml,mm,mr; //左边的空位,区间最大的空位,右边的空位
}node[N<<]; int id; void building(int l,int r,int p)//建树
{
node[p].l = l;
node[p].r = r;
node[p].mm=node[p].mr=node[p].ml= r-l+;
if(l==r) return;
int mid = (l+r)>>;
building(l,mid,lson);
building(mid+,r,rson);
} void judgeChange(int p) //向下更新,状态延迟标记,当搜索到整个区间一样时,向下更新一层,然后进行操作
{
if(node[p].mm==node[p].r-node[p].l+)
{
node[lson].ml=node[lson].mm=node[lson].mr=node[lson].r-node[lson].l+;
node[rson].ml=node[rson].mm=node[rson].mr=node[rson].r-node[rson].l+;
}
if(node[p].mm==)
{
node[lson].ml=node[lson].mm=node[lson].mr=;
node[rson].ml=node[rson].mm=node[rson].mr=;
}
} void findId(int p,int val) //查找可以开房间的起始位置
{
if(node[p].l==node[p].r&&val==) //当val为1并且已经达到叶子节点,说明没有孩子了,不必再往下查找
{
id = node[p].l;
return;
}
judgeChange(p); //状态延迟标记更新
if(node[p].mm>=val) //区间最大连续>=val时
{
if(node[lson].mm>=val) //优先左边搜索
{
findId(lson,val);
}
else if(node[rson].ml+node[lson].mr>=val) //然后中间
{
id = node[lson].r - node[lson].mr + ;
}
else if(node[rson].mm>=val) //最后右边
{
findId(rson,val);
}
}
} void Up(int p) //向上更新状态
{
node[p].ml = node[lson].ml;
node[p].mr = node[rson].mr;
if(node[lson].ml==node[lson].r-node[lson].l+)
{
node[p].ml+=node[rson].ml;
}
if(node[rson].mr==node[rson].r-node[rson].l+)
{
node[p].mr+=node[lson].mr;
}
node[p].mm = max(node[lson].mm,node[rson].mm);
node[p].mm = max(node[p].mm,node[lson].mr+node[rson].ml);
node[p].mm = max(node[p].mm,node[p].ml);
node[p].mm = max(node[p].mm,node[p].mr);
} void update(int l,int r,int p,int op) //更新
{
if(node[p].l==l&&node[p].r==r)
{
if(op==) node[p].ml=node[p].mm=node[p].mr=; //执行操作1
else node[p].ml=node[p].mm=node[p].mr=r-l+; //执行操作2
return;
}
judgeChange(p); //状态延迟标记更新
int mid = (node[p].l+node[p].r)>>;
if(r<=mid) update(l,r,lson,op);
else if(l>mid) update(l,r,rson,op);
else
{
update(l,mid,lson,op);
update(mid+,r,rson,op);
}
Up(p); //由左右孩子节点向上更新ml,mm,mr值
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
building(,n,);
while(m--)
{
int op,a,b;
scanf("%d",&op);
if(op==)
{
scanf("%d",&a);
id = ;
findId(,a); //查找可插入位置
printf("%d\n",id);
if(id) update(id,id+a-,,); //在id位置插入a个数,即在[id,id+a-1]插入
}
else if(op==)
{
scanf("%d%d",&a,&b);
update(a,a+b-,,); //在a位置删除b个数,即把在[a,a+b-1]区间清空
}
}
return ;
}

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 Hotel(线段树,区间合并)

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

  4. PKU 3667 Hotel(线段树)

    Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  5. POJ 1823 Hotel 线段树

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

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

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

  7. POJ 3667 Hotel(线段树)

    POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...

  8. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  9. [USACO08FEB]酒店Hotel 线段树

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

随机推荐

  1. FastDFS配置过程

    在我的生产环境中利用FastDFS实现动静分离的方案

  2. Matlb中break 和continue 语句

    有两个附加语句可以控制while 和for 循环:break 和continue 语句. break 语句可以中止循环的执行和跳到end 后面的第一句执行,而continue 只中止本次循环,然后返回 ...

  3. 本地环境phpStorm10+XDebug配置和断点调试

    安装环境:XAMPP;phpStorm版本10; windows 7 64bit. XAMPP.phpStorm 都直接安装在了D盘根目录,9999m目录建在D:\xampp\htocts下,即目录工 ...

  4. FontAwesome 奥森图标的学习

    很早之前,就看到大家在使用代码做出很漂亮的图标,但是觉得需求不是很大,所以就没有看,但是技多不压身,这次有时间来学习下. FontAwesome官方网站 1,下载文件包 里面有两个文件夹,css 和 ...

  5. 使用netbeans 搭建 JSF+SPRING 框架

    spring版本使用4,jsf版本2.2 jsf的配置文件faces-config.xml <?xml version='1.0' encoding='UTF-8'?> <faces ...

  6. EF架构~过滤导航属性等,拼接SQL字符串

    拼接T-SQL串,并使它具有通用性 好处:与服务器建立一次连接,给服务器发一条SQL命令,即可实现 代码如下: 1 /// <summary> 2 /// 构建Insert语句串 3 // ...

  7. Hql 中实用查询时候 引号的使用

    出错代码://List vlist = this.getHibernateTemplate().find("from AndroidCustomer ct where ct.token = ...

  8. left join 改写标量子查询

    数据库环境:SQL SERVER 2005 有一博彩的赔率是1:20,它有2张业务表:smuchs(投注表),lottery(开奖表). smuchs表有3个字段,分别是sno(投注号码).smuch ...

  9. 关于insertBefore

    insertBefore,看名字就是在某个元素前插入元素,但是其实它可以再文档任何元素强势插入. insertBefore用法: parent.insertBefore(newChild, refCh ...

  10. Mysql的权限管理

    权限管理 创建用户 语法:     create user '用户名'[@'主机名'][identified by '密码']; 示例: 说明:     用户名必须使用引号     '主机名'可以是以 ...