刷题总结——旅馆(bzoj1593线段树)
题目:
Description
奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N (1 <= N <= 50,000)间客房,它们在同一层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 贝茜一行,以及其他慕名而来的旅游者,都是一批批地来到旅馆的服务台,希望能订到D_i (1 <= D_i <= N)间连续的房间。服务台的接待工作也很简单:如果存在r满足编号为r..r+D_i-1的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字X_i、D_i 描述,表示编号为X_i..X_i+D_i-1 (1 <= X_i <= N-D_i+1)房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理M (1 <= M < 50,000)个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。
Input
* 第1行: 2个用空格隔开的整数:N、M
* 第2..M+1行: 第i+1描述了第i个请求,如果它是一个订房请求,则用2个数字 1、D_i描述,数字间用空格隔开;如果它是一个退房请求,用3 个以空格隔开的数字2、X_i、D_i描述
Output
* 第1..??行: 对于每个订房请求,输出1个独占1行的数字:如果请求能被满足 ,输出满足条件的最小的r;如果请求无法被满足,输出0
Sample Input
1 3
1 3
1 3
1 3
2 5 5
1 6
Sample Output
4
7
0
5
HINT
题解:
线段树维护区间连续最大值,区间左端点连续值,区间右端点连续值即可·····
我这里tag标记打了两个··一个订房一个退房···注意在打其中一个标记时把另外一个标记清空·····
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=5e4+;
int n,m,trle[N*],trri[N*],trmx[N*],tagclear[N*],tagfull[N*];
inline int R()
{
char c;int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
inline void update(int k,int l,int r,int mid)
{
if(trle[k*]==(mid-l+)) trle[k]=trle[k*]+trle[k*+];
else trle[k]=trle[k*];
if(trri[k*+]==(r-mid)) trri[k]=trri[k*+]+trri[k*];
else trri[k]=trri[k*+];
trmx[k]=max(max(trmx[k*],trmx[k*+]),trri[k*]+trle[k*+]);
}
inline void build(int k,int l,int r)
{
if(l==r) {trle[k]=trri[k]=trmx[k]=;return;}
int mid=(l+r)/;
build(k*,l,mid);build(k*+,mid+,r);
update(k,l,r,mid);
}
inline void pushdown(int k,int l,int r,int mid)
{
if(tagfull[k])
{
trle[k*]=trri[k*]=trmx[k*]=mid-l+;tagfull[k*]=true;tagclear[k*]=false;
trle[k*+]=trri[k*+]=trmx[k*+]=r-mid;tagfull[k*+]=true;tagclear[k*+]=false;
tagfull[k]=false;
}
if(tagclear[k])
{
trle[k*]=trri[k*]=trmx[k*]=trle[k*+]=trri[k*+]=trmx[k*+]=;
tagclear[k*]=tagclear[k*+]=true;tagfull[k*]=tagfull[k*+]=false;
tagclear[k]=false;
}
}
inline void full(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
{
trle[k]=trri[k]=trmx[k]=r-l+;tagfull[k]=true;tagclear[k]=false;return;
}
int mid=(l+r)/;pushdown(k,l,r,mid);
if(x<=mid) full(k*,l,mid,x,y);
if(y>mid) full(k*+,mid+,r,x,y);
update(k,l,r,mid);
}
inline void clear(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
{
trle[k]=trri[k]=trmx[k]=;tagclear[k]=true;tagfull[k]=false;return;
}
int mid=(l+r)/;pushdown(k,l,r,mid);
if(x<=mid) clear(k*,l,mid,x,y);
if(y>mid) clear(k*+,mid+,r,x,y);
update(k,l,r,mid);
}
inline int find(int k,int l,int r,int x)
{
int mid=(l+r)/;
pushdown(k,l,r,mid);
if(trle[k]>=x)
{
clear(,,n,l,l+x-);return l;
}
else if(trmx[k*]>=x) return find(k*,l,mid,x);
else if(trri[k*]+trle[k*+]>=x)
{
int temp=mid-trri[k*]+;
clear(,,n,mid-trri[k*]+,mid-trri[k*]+x);
return temp;
}
else if(trmx[k*+]>=x) return find(k*+,mid+,r,x);
else if(trri[k]>=x)
{
clear(,,n,r-x+,r);return r-x+;
}
}
int main()
{
//freopen("a.in","r",stdin);
n=R(),m=R();
build(,,n);int op,a,b;
while(m--)
{
op=R();
if(op==)
{
a=R();
if(trmx[]<a) printf("0\n");
else printf("%d\n",find(,,n,a));
}
if(op==)
{
a=R(),b=R();
full(,,n,a,a+b-);
}
}
return ;
}
刷题总结——旅馆(bzoj1593线段树)的更多相关文章
- 刷题向》关于线段树的区间开根号 BZOJ3211(NORMAL+)
这是一道关于线段树的区间开根号的裸题,没什么好讲的. 值得注意的是,因为有区间开根号的性质,所以我们每一次更改操作只能把更改区间所覆盖的所有元素全部查找,当然你直接找效率明显爆炸... 能够注意到,指 ...
- BZOJ_3038_上帝造题的七分钟2_线段树
BZOJ_3038_上帝造题的七分钟2_线段树 题意: XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分 ...
- 2018.06.29 NOIP模拟 旅馆(线段树)
旅馆 [问题描述] OIEROIEROIER 们最近的旅游计划,是到长春净月潭,享受那里的湖光山色,以及明 媚的阳光.你作为整个旅游的策划者和负责人,选择在潭边的一家著名的旅馆住 宿.这个巨大的旅馆一 ...
- Hotel 旅馆, 线段树查询,合并
C. Hotel 旅馆 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 OIER最近的旅游计划,是到长春净月潭,享受那里的湖光山色, ...
- 【刷题】BZOJ 4817 [Sdoi2017]树点涂色
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- bzoj 3779 重组病毒 好题 LCT+dfn序+线段树分类讨论
题目大意 1.将x到当前根路径上的所有点染成一种新的颜色: 2.将x到当前根路径上的所有点染成一种新的颜色,并且把这个点设为新的根: 3.查询以x为根的子树中所有点权值的平均值. 分析 原题codec ...
- jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)
传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...
- Bzoj3038 上帝造题的七分钟2 线段树
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1135 Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...
- B3038 上帝造题的七分钟2 线段树
这就是一道变得比较奇怪的线段树,维护每个区间的最大值和区间和,然后关键在于每次取根号的话数值下降的特别快,不用几次就都是1了,所以每次暴力单点修改,然后直接找区间最大值,假如区间最大值是1的话,就直接 ...
随机推荐
- 关于cocos2dx for lua资源加载优化方案
之前我写游戏加载都是从一个json文件写入要加载的文件名来实现加载,但是如果资源 比较多的情况下,会导致非常难管理,需要逐个写入.所以换了另外一种方式来加载文件. 首先,我是通过场景之前的切换时候,加 ...
- iOS下的2D仿射变换机制(CGAffineTransform相关)
仿射变换简介 仿射变换源于CoreGraphics框架,主要作用是绘制2D级别的图层,几乎所有iOS设备屏幕上的界面元素都是由CoreGraphics来负责绘制.而我们要了解的2D仿射变换是其下负责二 ...
- 配置Xcode的Device Orientation、AppIcon、LaunchImage
以下图片指出的 TARGETS→General 面板的信息. 下面我们讲讲根据 APP 需求配置我们的Xcode: 1.设置 Device Orientation,指定 APP 支持设备的方向 ,我们 ...
- 53. Maximum Subarray@python
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- 【two pointers 细节题】cf1041dD. Glider
像这样细节老是打挂不行啊…… A plane is flying at a constant height of hh meters above the ground surface. Let's c ...
- iPhone如何设置自定义铃声?无需连接电脑,轻松几步就搞定!
转载自: https://baijiahao.baidu.com/s?id=1594988016778457969&wfr=spider&for=pc 受够了iPhone自带的千篇一律 ...
- mysql替换表中某字段的某值
UPDATE `cases` SET `case_desc` = replace(`case_desc`, 'src="//tuku-assets.m.jia.com/assets/i ...
- GoF23种设计模式之结构型模式之组合模式
一.概述 将对象组合成树型结构以表示“部分--整体”的层次关系.组合模式使得用户对单个对象和组合对象的使用具有一致性. 二.适用性 1.你想表示对象的部分--整体层次结构的时候. 2.你希望用户忽略组 ...
- 设置vim 永久显示行号
永久显示行号:如果想让vim永久显示行号,则需要修改vim配置文件vimrc.如果没有此文件可以创建一个.在启动vim时,当前用户根目录下的vimrc文件会被自动读取,因此一般在当前用户的根目录下创建 ...
- LeetCode(162) Find Peak Element
题目 A peak element is an element that is greater than its neighbors. Given an input array where num[i ...