poj 3667 Hotel 线段树
来源:互联网 发布:免费进销存软件排名 编辑:程序博客网 时间:2024/05/21 16:34
题目链接:poj.org/problem?id=3667
题目大意:
有N间房,排成一排,每次入住连续编号为[r, r + D - 1]的房间,要求r最小;每次退房时会退掉连续编号为[X, X + D - 1]的房间。输入有两种形式:
1 入住D间房间,要求输出r最小
2 退掉一段房间
题目分析:
经典线段树问题。有插入、删除和查询操作。每次入住时查询并插入,退房时删除。
可以通过维护左端空房数,右端空房数和最大空房数三个空间来实现各个操作。
具体实现过程:
lf[]记录左端连续空房
rf[]记录右端连续空房
mf[]记录最长连续空房
dl[]标记该段房间的状态,也就是懒操作:0为空,1为满
update()实现对一段区间的更新
pushdown()使标记下传
query()查询最左所需连续房间编号
实现代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define maxn 50002<<2#define m ((l+r)>>1)#define ll (t<<1) // 左孩子#define rr (t<<1|1) // 右孩子#define ls l,m,ll // 左孩子参数#define rs m+1,r,rr //右孩子参数#define max(a,b) ((a)>(b)?(a):(b))int lf[maxn], rf[maxn], mf[maxn], dl[maxn];inline void pushdown(int l, int r, int t) { // 标记下传if (dl[t] != -1) {lf[ll] = rf[ll] = mf[ll] = (dl[ll] = dl[t]) ? 0 : (m - l + 1);lf[rr] = rf[rr] = mf[rr] = (dl[rr] = dl[t]) ? 0 : (r - m);dl[t] = -1;}}void update(int L, int R, int c, int l, int r, int t) {if (L <= l && r <= R) {lf[t] = rf[t] = mf[t] = (dl[t] = c) ? 0 : (r - l + 1);return;}pushdown(l, r, t);if (L <= m)update(L, R, c, ls);if (R > m)update(L, R, c, rs);// pushuplf[t] = lf[ll];rf[t] = rf[rr];if (lf[ll] == m - l + 1)lf[t] += lf[rr];if (rf[rr] == r - m)rf[t] += rf[ll];mf[t] = max(max(mf[ll], mf[rr]), rf[ll] + lf[rr]);}int query(int d, int l, int r, int t) { // 查询过程if (l == r)return l;pushdown(l, r, t); // 不要忘了标记下传if (mf[ll] >= d)return query(d, ls);else if (rf[ll] + lf[rr] >= d)return m - rf[ll] + 1;elsereturn query(d, rs);}int main() {int n, cs, c, d, x, p;scanf("%d %d", &n, &cs);// 建树lf[1] = rf[1] = mf[1] = n;dl[1] = 0;while (cs--) {scanf("%d", &c);if (c == 1) {scanf("%d", &d);if (d > mf[1])printf("0\n");else {p = query(d, 1, n, 1);printf("%d\n", p);update(p, p + d - 1, 1, 1, n, 1);}} else {scanf("%d %d", &x, &d);update(x, x + d - 1, 0, 1, n, 1);}}return 0;}
- POJ 3667 Hotel(线段树)
- 【线段树】poj 3667 Hotel
- POJ 3667 Hotel 线段树
- poj 3667 hotel #线段树
- POJ-3667 Hotel[线段树]
- POJ 3667 HOTEL 线段树
- POJ 3667 Hotel (线段树)
- poj 3667 Hotel 线段树
- POJ 3667 Hotel 线段树
- poj 3667 Hotel 线段树
- POJ 3667 Hotel 线段树
- 【线段树】 POJ 3667 Hotel
- poj 3667 Hotel(线段树)
- POJ - 3667 Hotel(线段树)
- POJ 3667 Hotel (线段树)
- POJ.3667 Hotel ( 线段树 )
- poj Hotel 线段树
- POJ 3667 Hotel 线段树区间合并
- C语言奇思妙想:求1+2+…+n,要求不能使用乘除法、for、while、if、else、s witch、case 等关键字以及条件判断语句(A?B:C)
- poj 1021 2D-Nim 图论
- MySQL SQL Tuning:深入理解Order By
- cakephp用户注册实例
- Java SE——方法重载与继承
- poj 3667 Hotel 线段树
- Windows的任务调度机制
- C++面试宝典(转)
- 单元测试
- static??
- GDB_Linux调试器
- u-boot代码学习问题和移植问题汇总
- Android中Service类onStartCommand
- centos vsftpd 553 Could not create file解决方法