经典线段树的题。

每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度。

由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小:

1.如果当前区间的最大空房间长度小于要寻找的长度,说明不会找到符合的区间,直接退出。

2.如果左子区间的最大空房间长度大于等于要寻找的长度,那么应该进入左子区间查找。

3.否则,如果左子区间的右端点连续空房间长度 + 右子区间的左端点连续空房间的长度 大于等于 要寻找的长度则直接返回左子区间右端点起始空房间下标。

4.否则,进入右区间寻找。

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 2e5;
struct node{int l, r;int len, lenl, lenr;int tag; //0代表全空  1代表全满 -1代表混杂
}t[maxn];void build(int l, int r, int cur){t[cur].l = l, t[cur].r = r;t[cur].len = t[cur].lenl = t[cur].lenr = r - l + 1;t[cur].tag = 0; if(l == r) return;int mid = (l + r) / 2;build(l, mid, cur << 1);build(mid + 1, r, (cur << 1) + 1);
}void lazy(int cur){   if(t[cur].l == t[cur].r) return;if(t[cur].tag >= 0) {  //覆盖 int l = cur << 1, r = (cur << 1) + 1;int val;if(t[cur].tag == 0) val = t[l].r - t[l].l + 1;else val = 0;t[l].len = t[l].lenl = t[l].lenr = val;if(t[cur].tag == 0) val = t[r].r - t[r].l + 1;else val = 0;t[r].len = t[r].lenl = t[r].lenr = val;t[r].tag = t[l].tag = t[cur].tag;}
}int search(int len, int cur){if(t[cur].len < len) return 0;int l = t[cur].l, r = t[cur].r;if(l == r) return l;lazy(cur);if(t[cur << 1].len >= len) return search(len, cur << 1);else if(t[cur << 1].lenr + t[(cur << 1) + 1].lenl >= len) return t[cur << 1].r - t[cur << 1].lenr + 1;else if(t[(cur << 1) + 1].len >= len) return search(len, (cur << 1) +1);
}void update(int l, int r, int tag, int cur){int l1 = t[cur].l, r1 = t[cur].r;if(l1 == l && r1 == r){t[cur].tag = tag;int val;if(tag) val = 0;else val = r1 - l1 + 1;t[cur].len = t[cur].lenl = t[cur].lenr = val;return;}lazy(cur);int mid = (l1 + r1) / 2;if(r <= mid) update(l, r, tag, cur << 1);else if(l >= mid + 1) update(l, r, tag, (cur << 1) + 1);else {update(l, mid, tag, cur << 1);update(mid + 1, r, tag, (cur << 1) + 1);}int c1 = cur << 1, c2 = (cur << 1) + 1;int w = t[c1].lenr + t[c2].lenl;t[cur].lenl = t[c1].lenl, t[cur].lenr = t[c2].lenr;if(t[c1].tag == 0) t[cur].lenl = w;if(t[c2].tag == 0) t[cur].lenr = w;t[cur].len = max(t[c1].len, t[c2].len);t[cur].len = max(w, t[cur].len);t[cur].len = max(t[cur].len, t[cur].lenr);t[cur].len = max(t[cur].len, t[cur].lenl);if(t[cur].len == 0) t[cur].tag = 1;else if(t[cur].len == r1 - l1 + 1) t[cur].tag = 0;else t[cur].tag = -1;
}int main(){int n,q;while(scanf("%d%d", &n, &q) == 2){build(1, n, 1);int a, b, c;for(int i = 0; i < q; ++i){scanf("%d", &a);if(a == 1){scanf("%d", &b);int x = search(b, 1);printf("%d\n", x);if(x != 0) update(x, x + b - 1, 1, 1);}else {scanf("%d%d", &b, &c);update(b, b + c - 1, 0, 1);}}}return 0;
}

如有不当之处欢迎指出!

poj Hotel 线段树相关推荐

  1. 【转】poj 1823 hotel 线段树【Good】

    题意:一个hotel,有n个连续的房间,开始时均无人住宿 共有3种操作 1 a b 从a开始连续b个房间全部旅客住宿 [a,a+b-1]; 2 a b 从a开始连续b个房间全部旅客离开 [a,a+b- ...

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

    题意: 给定长度为n的区间 ,有2个操作: 操作1: 在区间中靠左放k个元素,输出新放入元素中最左边的位置,如果放不下输出 0: 操作2 : 清空 l 到 l+w-1这一段区间的元素 这里有一个状态转 ...

  3. POJ 3667 Hotel 线段树区间合并

    线段树的区间合并,其中lsum代表区间左边最大连续长度,rsum代表区间最大连续长度,msum代表区间 最大连续长度.因为本题是查询连续区间的左端点,那么如果左儿子满足条件,就继续查询左儿子,左儿 子 ...

  4. POJ 3468 线段树+lazy标记

    lazy标记   Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u  Submit S ...

  5. POJ 3264 线段树

    题意 传送门 POJ 3264 题解 线段树维护区间的最大值和最小值即可. #include <cstdio> #include <cstring> #include < ...

  6. poj(2325)线段树

    这里介绍另外一种解法,此题可以用线段树,可以用树状数组 其实这题求的都是下面的和左面的,线段树这种数组结构刚好可以满足,为什么呢?这里稍微解释下吧,也有助于以后的复习 看上面这个图,[1,1],[2, ...

  7. poj 3468 线段树

    线段树的 建立build(初始化+左右相等+两个递归+别忘了sum)+更新update(递归出口+更新delta+三向递归+修正当前节点的value)+查找query(如果左右相等+更新delta+三 ...

  8. POJ - 2528 线段树+离散化

    其实很早就在白书上的常用技巧上 看到离散化的操作,但是之前一直没遇到过需要离散化的题目(应该是我太菜的缘故),所以一直也没怎么重视,下面说说这道题目的考点,也就是离散化. 什么是离散化呢?请先自行百度 ...

  9. poj 2777(线段树+区间染色)

    解题思路:这道题利用了线段树+位运算的思想,由于颜色的种类只有30种,所以int可以存下来,所以我们在线段树的节点里面加上status的状态信息,表示这段区间内的颜色信息,而且我们可以知道,父节点的s ...

最新文章

  1. php把单词切割成数组,PHP – 将单词分解为数组
  2. 笔记-项目立项管理-项目的可行性研究-可行性研究内容
  3. 微信小程序 列表的分页实现(最新的最简易的实现方式+思路,附代码)
  4. 高校c语言题库,C语言-中国大学mooc-题库零氪
  5. db2 语句包括不必要的列表_DB2 SQL0956C 数据库堆中没有足够的处理空间可用来处理此语句...
  6. python实例属性与类属性_Python 面向对象编程:类的创建与初始化、实例属性与方法、类属性与方法...
  7. OA系统选型:选择好的工作流引擎
  8. 《学习OpenCV3》第10章 滤波与卷积
  9. [No0000FF]鸡蛋煮熟了蛋黄为什么发黑?
  10. matlab开环传递函数 求单位负反馈的系统传递函数,利用matlab由开环传递函数求闭环传递函数并求其单位冲击和阶跃响应...
  11. 物料的周期单位价格突然高得离谱
  12. C++QT开发——Xml、Json解析
  13. 服务器安装系统提示加载驱动程序,解决安装win7的提示“加载驱动程序”的问题...
  14. Python办公自动化之PPT幻灯片自动化:使用Python制作PPT 操作PPT
  15. “搜索大战”正式打响,微软发布ChatGPT版搜索引擎和浏览器
  16. 吴彩强:从表征到行动---意向性的自然主义进路
  17. 人工智能医疗检测:微核细胞情况自动检出率可达90%
  18. php摇号 中标 程序,摇号信息系统招标公告
  19. java组件及事件处理(11)--ActionListener一个窗口,两个事件
  20. 如何用C语言实现三子棋的人机博弈

热门文章

  1. ASPICE 与 功能安全过程融合 | 单条需求的规范表达形式
  2. 艺体计算机教师考核细则,艺体教师考核细则.doc
  3. mac 连接上l2tp但是无法访问公网
  4. 如何查看电脑运行记录
  5. 风很大的PMP证书真有这么厉害?这是被腾讯/华为招聘时所提到过的证书
  6. axios+Vant+vue+jq重构jq月经周期计算器源代码(兼容移动端)
  7. Axure 9 案例教程进阶篇之课程简介(带你玩转高交互设计)
  8. 手撕自动驾驶算法——IMU测量模型、运动模型、误差模型
  9. jQurey入门以及选择器
  10. Cris 的 Docker 学习笔记