题目链接:http://poj.org/problem?id=3667

题目大意:一共有n个房间,初始时都是空的,现在有m个操作,操作有以下两种:

1.1 d :询问是否有连续d个空的房间,若有则输出连续房间的起始编号,若无则输出0

2.2 xi d:将第xi个房间至第xi+d-1个房间清空

解题思路:线段树维护区间最大连续长度,tree[cur].lm代表以区间左端点为起点的连续段的长度 tree[cur].rm代表以区间右端点为终点的连续段的长度,tree[2*cur].rm+tree[2*cur+1].lm代表包含该区间中点的连续段的长度 这是个隐含值(中间连续段),则区间内最长连续段值不止要从左右子节点的最长连续段中择最大 还要考虑该区间的中间连续段即tree[cur].len=max(tree[2*cur].rm+tree[2*cur+1].lm,max(tree[2*cur].len,tree[2*cur+1].len));

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=;
int n,m;
struct node{
int lm,rm,len,cov;
}tree[maxn<<]; void pushup(int len,int rt){
tree[rt].lm=tree[rt<<].lm;
if(tree[rt].lm==len-(len>>)){
tree[rt].lm+=tree[rt<<|].lm;
}
tree[rt].rm=tree[rt<<|].rm;
if(tree[rt].rm==(len>>)){
tree[rt].rm+=tree[rt<<].rm;
}
tree[rt].len=max(tree[rt<<].rm+tree[rt<<|].lm,max(tree[rt<<].len,tree[rt<<|].len));
}
void pushdown(int len,int rt){
if(tree[rt].cov!=-){
tree[rt<<].cov=tree[rt<<|].cov=tree[rt].cov;
tree[rt<<].lm=tree[rt<<].rm=tree[rt<<].len=tree[rt].cov?:(len-(len>>));
tree[rt<<|].lm=tree[rt<<|].rm=tree[rt<<|].len=tree[rt].cov?:(len>>);
tree[rt].cov=-;
}
}
void build(int l,int r,int rt){
tree[rt].cov=-;
tree[rt].lm=tree[rt].rm=tree[rt].len=r-l+;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
}
void update(int L,int R,int val,int l,int r,int rt){
if(L<=l&&R>=r){
tree[rt].cov=val;
tree[rt].lm=tree[rt].rm=tree[rt].len=val?:(r-l+);
return;
}
int mid=(l+r)>>;
pushdown(r-l+,rt);
if(L<=mid) update(L,R,val,l,mid,rt<<);
if(R>mid) update(L,R,val,mid+,r,rt<<|);
pushup(r-l+,rt);
}
int query(int w,int l,int r,int rt){
if(l==r)return ;
pushdown(r-l+,rt);
int mid=(l+r)>>;
if(tree[rt<<].len>=w) return query(w,l,mid,rt<<);
else if(tree[rt<<].rm+tree[rt<<|].lm>=w) return mid-tree[rt<<].rm+;
else return query(w,mid+,r,rt<<|);
} int main(){
scanf("%d%d",&n,&m);
build(,n,);
while(m--){
int op,x,cnt,ans;
scanf("%d",&op);
if(op==){
scanf("%d",&cnt);
if(tree[].len<cnt) ans=;
else ans=query(cnt,,n,);
printf("%d\n",ans);
if(ans>)
update(ans,ans+cnt-,,,n,);
}else{
scanf("%d%d",&x,&cnt);
update(x,x+cnt-,,,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. WebApi系列知识总结

    WebApi系列知识 一.webApi项目搭建 1.新建WebApi项目 (1) (2) (3) (4) Areas – HelpPage – App_Start – HelpPageConfig.c ...

  2. React Native商城项目实战01 - 初始化设置

    1.创建项目 $ react-native init BuyDemo 2.导入图片资源 安卓:把文件夹放到/android/app/src/main/res/目录下,如图: iOS: Xcode打开工 ...

  3. Selenium IDE环境部署

    摘自https://blog.csdn.net/ywyxb/article/details/59103683 Selenium IDE环境部署 - Firefox浏览器 Firefox-ESR版本下载 ...

  4. [转]delphi 防止刷新时闪烁的终极解决办法

    { 防止刷新时闪烁的终极解决办法(对付双缓冲无效时) }Perform($000B, 0, 0); //锁屏幕 防止闪烁 // 做一些会发生严重闪烁的事情.. //解锁屏幕并重画Perform($00 ...

  5. Monkey测试:Monkey的简单使用

    Monkey是Android SDK提供的一个命令行工具,可以简单方便的发送伪随机的用户事件流,对Android APP做压力(稳定性)测试.主要是为了测试app是否存在无响应和崩溃的情况. 一.环境 ...

  6. laravel 配置双模板引擎

    有时候我们可能有这种需求,pc 和 mobile 端显示的页面不一样,这个时候,我们就需要判断设备类型: ****我们用  composer require whichbrowser/parser  ...

  7. Java多线程学习——wait方法(管道法/生产者消费者模式)

    简单介绍管道法: 生产者生产数据输送到管道,消费者从管道拿出数据,管道为空消费者等待,管道满生产者生产,消费者消费生产者生产,生产者生产消费者消费. public class Corn { //要生产 ...

  8. Java多线程学习——join方法的使用

    join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A, ...

  9. python+selenium操作cookie

    WebDriver提供了操作Cookie的相关方法,可以读取.添加和删除cookie信息. WebDriver操作cookie的方法: get_cookies(): 获得所有cookie信息. get ...

  10. Python_ONLINE_习题集_1 递归

    1.1 使用递归实现:计算某个数的阶乘 def func(x): if x == 2: return 2 else: return x*func(x-1) a = func(4) print(a) 2 ...