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

题意:

有N个房间,M次操作。有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。(2)"2 b len",把起点为b长度的len的房间清空,即退房。

思路:

区间合并的线段树题。

其实如果单点更新和区间更新做得多了的话,区间合并也就不难了。

对于这道题,我们用线段树维护三个值,从左端开始的连续空房间数,从右边开始的连续空房间数,以及整个区间内最大的连续空房间数。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m; struct node //维护从左端开始的最大连续空房间,从右端开始的最大连续空房间,总的最大连续空房间
{
int l,r;
int ls,rs,sum;
}t[maxn<<]; int lazy[maxn<<]; void PushUp(int o)
{
t[o].ls=t[o<<].ls;
t[o].rs=t[o<<|].rs;
int mid=(t[o].l+t[o].r)>>;
if(t[o].ls==mid-t[o].l+) t[o].ls+=t[o<<|].ls; //如果左半部分都是空房间,那么可以与右半部分的左边空房间连起来
if(t[o].rs==t[o].r-mid) t[o].rs+=t[o<<].rs;
t[o].sum=max(max(t[o<<].sum,t[o<<|].sum),t[o<<].rs+t[o<<|].ls);
} void PushDonw(int o)
{
if(lazy[o]!=-)
{
lazy[o<<]=lazy[o<<|]=lazy[o];
if(lazy[o]) //为1的话要将该区间置满
{
t[o<<].ls=t[o<<].rs=t[o<<].sum=;
t[o<<|].ls=t[o<<|].rs=t[o<<|].sum=;
}
else //为0的话要将该区间置空
{
t[o<<].ls=t[o<<].rs=t[o<<].sum=t[o<<].r-t[o<<].l+;
t[o<<|].ls=t[o<<|].rs=t[o<<|].sum=t[o<<|].r-t[o<<|].l+;
}
lazy[o]=-;
}
} void build(int l, int r, int o)
{
lazy[o]=-;
t[o].l=l;
t[o].r=r;
t[o].ls=t[o].rs=t[o].sum=r-l+;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,o<<);
build(mid+,r,o<<|);
} void update(int ql, int qr, int l, int r, int flag, int o)
{
if(ql<=l && qr>=r)
{
if(flag) t[o].ls=t[o].rs=t[o].sum=;
else t[o].ls=t[o].rs=t[o].sum=r-l+;
lazy[o]=flag;
return;
}
PushDonw(o);
int mid=(l+r)>>;
if(ql<=mid) update(ql,qr,l,mid,flag,o<<);
if(qr>mid) update(ql,qr,mid+,r,flag,o<<|);
PushUp(o);
} int query(int l, int r, int num, int o)
{
if(l==r) return l;
PushDonw(o);
int mid=(l+r)>>;
if(t[o<<].sum>=num) return query(l,mid,num,o<<);
else if(t[o<<].rs+t[o<<|].ls>=num) return mid-t[o<<].rs+;
else return query(mid+,r,num,o<<|);
} int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
build(,n,);
while(m--)
{
int op;
scanf("%d",&op);
if(op==)
{
int x;
scanf("%d",&x);
if(t[].sum<x) {puts("");continue;}
int pos=query(,n,x,);
printf("%d\n",pos);
update(pos,pos+x-,,n,,);
}
else
{
int s,t;
scanf("%d%d",&s,&t);
update(s,s+t-,,n,,);
}
}
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 & 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. Poj 3667——hotel——————【线段树区间合并】

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

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

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

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

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

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

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

随机推荐

  1. (c++) int 转 string,char*,const char*和string的相互转换

    一.int 和string的相互转换 1 int 转化为 string c++ //char *itoa( int value, char *string,int radix); // 原型说明: / ...

  2. 如何实现在H5里调起高德地图APP?

    http://www.cnblogs.com/milkmap/p/5912350.html 这一篇文章,将讲述如何在H5里调起高德地图APP,并展示兴趣点.适合于展示某个餐馆,商场等,让用户自行选择前 ...

  3. Python中如何获取类属性的列表

    这篇文章主要给大家介绍了在Python中如何获取类属性的列表,文中通过示例代码介绍的很详细,相信对大家的学习或者工作具有一定的参考借鉴价值,有需要的朋友可以参考借鉴,下面来一起看看吧. 前言 最近工作 ...

  4. PostgreSQL远程连接配置

    postgresql默认情况下,远程访问不能成功,如果需要允许远程访问,需要修改两个配置文件,说明如下: 1.postgresql.conf 将该文件中的listen_addresses项值设定为“* ...

  5. Perl的变量及语境(一)

    Perl语言中的大部分语句表达式后都紧接一个分号,分隔不同的Perl语句. perl解释器能一次完成编译和运行这两个动作. perl通过一对反引号"``"来表示运行外部命令. 也可 ...

  6. html lang属性

    HTML 的 lang 属性可用于网页或部分网页的语言.这对搜索引擎和浏览器是有帮助的. 根据 W3C 推荐标准,您应该通过 <html> 标签中的 lang 属性对每张页面中的主要语言进 ...

  7. python3 字典的常用方法

    字典的方法(可能需要重新整理) 函数 说明 D代表字典对象   D.clear() 清空字典 D.pop(key) 移除键,同时返回此键所对应的值 D.copy() 返回字典D的副本,只复制一层(浅拷 ...

  8. idea 上搭建 Mybatis 逆向工程

    网盘地址:https://pan.baidu.com/s/1VAILpdgQbFk9t89eEv_nWQ 提取码:xdyc

  9. thinkphp相关

    thinkphp相关1.thinkphp调试sql方法:echo M("table_name")->getLastSql(); 2. 条件查询设置多个条件参数的写法:(1). ...

  10. 如何在Qt Creator中创建pri文件,以及pri文件的说明

    初学Qt的人可还不会接触到这个问题,但是一旦你开始编写某个较大项目的时候,这个问题就不可避免需要解决. 对于大神们来讲可能这是个很简单的问题,但是对于新手来说,想要搞清楚需要下很大功夫. 怎么创建pr ...