题目链接

题目

题目描述

The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel has N (1 ≤ N ≤ 50,000) rooms all located on the same side of an extremely long hallway (all the better to see the lake, of course).

The cows and other visitors arrive in groups of size Di (1 ≤ Di ≤ N) and approach the front desk to check in. Each group i requests a set of Di contiguous rooms from Canmuu, the moose staffing the counter. He assigns them some set of consecutive room numbers r..r+Di-1 if they are available or, if no contiguous set of rooms is available, politely suggests alternate lodging. Canmuu always chooses the value of r to be the smallest possible.

Visitors also depart the hotel from groups of contiguous rooms. Checkout i has the parameters Xi and Di which specify the vacating of rooms Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1). Some (or all) of those rooms might be empty before the checkout.

Your job is to assist Canmuu by processing M (1 ≤ M < 50,000) checkin/checkout requests. The hotel is initially unoccupied.

输入描述

  • Line 1: Two space-separated integers: N and M
  • Lines 2..M+1: Line i+1 contains request expressed as one of two possible formats: (a) Two space separated integers representing a check-in request: 1 and Di (b) Three space-separated integers representing a check-out: 2, Xi, and Di

输出描述

  • Lines 1.....: For each check-in request, output a single line with a single integer r, the first room in the contiguous sequence of rooms to be occupied. If the request cannot be satisfied, output 0.

示例1

输入

10 6
1 3
1 3
1 3
1 3
2 5 5
1 6

输出

1
4
7
0
5

题解

知识点:线段树,二分。

考虑连续区间的权值最大值,需要维护三个信息,区间连续空房个数 \(emp\) 、区间从左端点开始的连续空房个数 \(lemp\) 、区间从右端点开始的连续空房的个数 \(remp\) 。

合并时, \(mx\) 为左右子区间 \(mx\) 和左子区间 \(remp\) 加右子区间 \(lemp\) 之和取最大值。 \(lemp,remp\) 需要考虑跨越左右区间的特殊情况,因此需要维护区间长度 \(len\) 。例如,若左子区间的 \(lemp\) 等于左子区间的 \(len\) ,那么区间 \(lemp\) 就是左子区间 \(len\) 加右子区间 \(lemp\) 否则继承左子区间的 \(lemp\) 即可,区间 \(remp\) 同理。

因此,区间信息需要维护 \(len,emp,lemp,remp\) 。

接下来是查找第一个连续空位大于等于 \(val\) 的位置,利用线段树上二分即可解决。首先判断是否存在,之后分三类情况:

  1. 若左子区间 \(emp\) 大于等于 \(val\) ,则查询左子区间。
  2. 否则若跨越左右子区间的空位,即左子区间的 \(remp\) 加右子区间的 \(lemp\) 之和,大于等于 \(val\) ,则直接返回位置。
  3. 否则查询右子区间。

区间修改维护一个信息,修改种类 \(upd\) , 有三个值 \(0/1/-1\) 表示未修改、全部入住、全部离开。 修改很朴素,看代码就行。

时间复杂度 \(O((n+m) \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; struct T {
int len;
int lemp, remp;
int emp;
static T e() { return{ 0,0,0,0 }; }
friend T operator+(const T &a, const T &b) {
return{
a.len + b.len,
a.lemp == a.len ? a.len + b.lemp : a.lemp,
b.remp == b.len ? a.remp + b.len : b.remp,
max({a.emp,b.emp,a.remp + b.lemp})
};
}
}; struct F {
int upd;
static F e() { return { 0 }; }
T operator()(const T &x) {
if (upd == 1)
return{
x.len,
0,0,
0
};
if (upd == -1)
return{
x.len,
x.len,x.len,
x.len
};
return x;
}
F operator()(const F &g) {
return { upd ? upd : g.upd };
}
}; class SegmentTreeLazy {
int n;
vector<T> node;
vector<F> lazy; void push_down(int rt) {
node[rt << 1] = lazy[rt](node[rt << 1]);
lazy[rt << 1] = lazy[rt](lazy[rt << 1]);
node[rt << 1 | 1] = lazy[rt](node[rt << 1 | 1]);
lazy[rt << 1 | 1] = lazy[rt](lazy[rt << 1 | 1]);
lazy[rt] = F::e();
} void update(int rt, int l, int r, int x, int y, F f) {
if (r < x || y < l) return;
if (x <= l && r <= y) return node[rt] = f(node[rt]), lazy[rt] = f(lazy[rt]), void();
push_down(rt);
int mid = l + r >> 1;
update(rt << 1, l, mid, x, y, f);
update(rt << 1 | 1, mid + 1, r, x, y, f);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
} int query(int rt, int l, int r, int val) {
if (l == r) return l;
push_down(rt);
int mid = l + r >> 1;
if (node[rt << 1].emp >= val) return query(rt << 1, l, mid, val);
if (node[rt << 1].remp + node[rt << 1 | 1].lemp >= val) return mid - node[rt << 1].remp + 1;
return query(rt << 1 | 1, mid + 1, r, val);
} public:
SegmentTreeLazy(int _n = 0) { init(_n); } void init(int _n) {
n = _n;
node.assign(n << 2, T::e());
lazy.assign(n << 2, F::e()); function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) return node[rt] = { 1,1,1,1 }, void();
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
} void update(int x, int y, F f) { update(1, 1, n, x, y, f); } int query(int val) {
if (node[1].emp < val) return 0;
return query(1, 1, n, val);
}
}; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
SegmentTreeLazy sgt(n);
while (m--) {
int op;
cin >> op;
if (op == 1) {
int d;
cin >> d;
int pos = sgt.query(d);
if (pos) sgt.update(pos, pos + d - 1, { 1 });
cout << pos << '\n';
}
else {
int x, d;
cin >> x >> d;
sgt.update(x, x + d - 1, { -1 });
}
}
return 0;
}

NC24961 Hotel的更多相关文章

  1. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  2. ACM: Hotel 解题报告 - 线段树-区间合并

    Hotel Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description The ...

  3. HDU - Hotel

    Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...

  4. 【POJ3667】Hotel

    Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...

  5. POJ-2726-Holiday Hotel

    Holiday Hotel   Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8302   Accepted: 3249 D ...

  6. Method threw 'org.hibernate.exception.SQLGrammarException' exception. Cannot evaluate com.hotel.Object_$$_jvst485_15.toString()

    数据库字段和类Object属性不匹配,Method threw 'org.hibernate.exception.SQLGrammarException' exception. Cannot eval ...

  7. poj 3667 Hotel(线段树,区间合并)

    Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...

  8. [POJ3667]Hotel(线段树,区间合并)

    题目链接:http://poj.org/problem?id=3667 题意:有一个hotel有n间房子,现在有2种操作: 1 a,check in,表示入住.需要a间连续的房子.返回尽量靠左的房间编 ...

  9. 【BZOJ】【3522】【POI2014】Hotel

    暴力/树形DP 要求在树上找出等距三点,求方案数,那么用类似Free Tour2那样的合并方法,可以写出: f[i][j]表示以 i 为根的子树中,距离 i 为 j 的点有多少个: g[i][j]表示 ...

  10. Codeforces Round #336 (Div. 2) A. Saitama Destroys Hotel 模拟

    A. Saitama Destroys Hotel   Saitama accidentally destroyed a hotel again. To repay the hotel company ...

随机推荐

  1. MAUI使用Masa blazor组件库

    上一篇(点击阅读)我们实现了UI在Web端(Blazor Server/Wasm)和客户端(Windows/macOS/Android/iOS)共享,这篇我加上 Masa Blazor组件库的引用,并 ...

  2. [转帖]ipv6相关内核参数配置的优化实践

    https://zhuanlan.zhihu.com/p/605217713 调整ARP缓存大小 这个参数通常需要在高负载的访问服务器上增加.比如繁忙的网络(或网关/防火墙 Linux 服务器),再比 ...

  3. [转帖]badboy与jmeter的结合使用

    https://blog.csdn.net/weixin_41754309/article/details/107106855 欢迎关注[无量测试之道]公众号,回复[领取资源], Python编程学习 ...

  4. [转帖]VMware-ovftool命令行部署与导出镜像

    ESXI6.0之后管理为WEB,OVF导出/部署是个渣渣,如果虚拟机文件过大,一般会报网络异常中断而失败,可使用官方ovftool工具解决,快而方便,支持linux和Mac OSX,可脚本操作,批量处 ...

  5. [转帖]Web性能优化工具WebPageTest(三)——本地部署(Windows 7版本)

    http://www.zlprogram.com/Show/30/30117.shtml 这次先能够使用PC端的浏览器测试,首先需要下载官方的发布版本"WebPageTest 3.0&quo ...

  6. 【转帖】Linux 调优篇 :虚拟化调优(irqbalance 网卡中断绑定)* 贰

    一.网络流量上不去二.中断绑定2.1 关闭中断平衡守护进程2.2 脱离中断平衡守护进程2.3 手动设置中断的CPU亲和性三. 总结 一.网络流量上不去 在Linux的网络调优方面,如果你发现网络流量上 ...

  7. 【转帖】Linux创建软连接出现的错误及解决方法

    问题: 创建软连接以后,使用cd 软连接路径显示没有那个文件或目录. 创建过程及切换结果,如图: 原因: 路径一定要写成绝对路径!!! 解决办法: 了解创建软连接的命令: ln -s 源文件 目标文件 ...

  8. SQLServer 隔离级别的简单学习

    SQLServer 隔离级别的简单学习 背景 上周北京一个项目出现了卡顿的现象. 周末开发测试加紧制作测试发布了补丁,但是并没有好转. 上周四时跟研发訾总简单沟通过, 怀疑是隔离级别有关系.但是不敢确 ...

  9. [转帖]文件系统读写性能fio测试方法及参数详解

    简介 Fio 是一个 I/O 工具,用来对硬件进行压力测试和验证,磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类. Fio支持13种不同的I/O引擎,包括:sync, ...

  10. jmaps

    #!/bin/bash # # jmaps - creates java /tmp/perf-PID.map symbol maps for all java processes. # # This ...