poj Hotel 线段树
经典线段树的题。
每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度。
由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小:
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 线段树的更多相关文章
- poj 2886 线段树+反素数
Who Gets the Most Candies? Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12744 Acc ...
- [USACO08FEB]酒店Hotel 线段树
[USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...
- poj 3667 Hotel (线段树)
http://poj.org/problem?id=3667 Hotel Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 94 ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- POJ 1823 Hotel 线段树
题目链接 线段树的区间合并. 和上一题差不多....第三种操作只需要输出maxx[1]的值就可以. #include <iostream> #include <vector> ...
- poj 3468(线段树)
http://poj.org/problem?id=3468 题意:给n个数字,从A1 …………An m次命令,Q是查询,查询a到b的区间和,c是更新,从a到b每个值都增加x.思路:这是一个很明显的线 ...
- POJ——3264线段树
题目: 输入两个数(m,n),m表示牛的头数,n表示查询的个数.查询时输入两个数(x,y),表示查询范围的起始值和终止值,查询结果是,这个区间内牛重量的最大值减去牛重量的最小值,数量级为1000,00 ...
- POJ 2828 线段树(想法)
Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 15422 Accepted: 7684 Desc ...
- PKU 3667 Hotel(线段树)
Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...
随机推荐
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- 基于Elasticsearch搜索平台设计
背景 随着公司业务的高速发展以及数据爆炸式的增长,当前公司各产线都有关于搜索方面的需求,但是以前的搜索服务系统由于架构与业务上的设计,不能很好的满足各个业务线的期望,主要体现下面三个问题: 不能支持对 ...
- 布衣之路(一):VMware虚拟机+CentOS系统安装
前言:布衣博主乃苦逼的Java程序猿一枚,虽然工作中不会涉及系统运维,但是开发的项目总还是要部署到服务器做一些负载均衡.系统兼容性测试.系统集成等等骚操作,而这些测试性的操作不可能直接SSH远程运维的 ...
- Java 解压zip压缩包
因为最近项目需要批量上传文件,而这里的批量就是将文件压缩在了一个zip包里,然后读取文件进行解析文件里的内容. 因此需要先对上传的zip包进行解压.以下直接提供代码供参考: 1.第一个方法是用于解压z ...
- ContextLoaderListener加载过程
在web.xml中,配置ContextLoaderListener <!-- 配置Listener,用来创建Spring容器 --> <listener> <listen ...
- Java多线程基础(二)
信号量Semaphore,类似于锁的功能,用于多线程中对一组资源的控制. acquire方法用于尝试获取一个资源,未获取前将一直等待.release用于释放一个资源,release的前提是已经获得了一 ...
- 《Thinking in Java》学习笔记(一)
服务器端的编程可以参考另一本书<企业Java编程>(Thinking in Enterprise Java). 1.基本类型 基本型别 大小 最小值 最大值 默认值 boolean -- ...
- 洛谷 [P3973] 线性代数
最大权闭合子图,神题 这不是线性代数,这是网络流. 我们看见这是一堆矩阵的运算,而且最后变成了一个数,那么我们就想到,把这个矩阵乘法的过程用具体的数字推出来 我们发现,a是一个01矩阵,然后其实就可以 ...
- JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】
1.PreparedStatement对象 PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时, ...
- 项目中引入composer
众所周知,composer可以自定义加载插件库和依赖,它也是用PHP写的,怎样在自己的项目中引入并使用composer呢?. 1.新建一个项目,在项目的根目录创建composer.json文件,用过一 ...