[USACO08FEB]酒店Hotel 线段树
[USACO08FEB]酒店Hotel 线段树
其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可。
void push_up(int x, int l, int r){
int mid=(l+r)>>1;
if(sum[lson]==mid-l+1) lmax[x]=sum[lson]+lmax[rson];
else lmax[x]=lmax[lson];
if(sum[rson]==r-(mid+1)+1) rmax[x]=sum[rson]+rmax[lson];
else rmax[x]=rmax[rson];
sum[x]=max(max(sum[lson], sum[rson]), rmax[lson]+lmax[rson]);
}
另外,查询时按顺序判断左节点、跨左右节点、右节点是否存在空房大于\(x\)的情况,有则递归下去,这样保证找到最左区间。
#include <cstdio>
#include <algorithm>
#define MAXN 50005
#define MAXM MAXN*4
using namespace std;
int n,m;
inline int read(){
char ch=getchar();int s=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s;
}
#define tag_none 0
#define tag_book 1
#define tag_unbook 2
#define lson (x<<1)
#define rson (x<<1|1)
int lmax[MAXM],rmax[MAXM],sum[MAXM],lazy[MAXM];
void push_down(int x, int l, int r){
if(lazy[x]==tag_none) return;
lazy[lson]=lazy[rson]=lazy[x];
if(lazy[x]==tag_book){
sum[lson]=lmax[lson]=rmax[lson]=0;
sum[rson]=lmax[rson]=rmax[rson]=0;
}else{
int mid=(l+r)>>1;
sum[lson]=lmax[lson]=rmax[lson]=mid-l+1;
sum[rson]=lmax[rson]=rmax[rson]=r-(mid+1)+1;
}
lazy[x]=tag_none;
}
void push_up(int x, int l, int r){
int mid=(l+r)>>1;
if(sum[lson]==mid-l+1) lmax[x]=sum[lson]+lmax[rson];
else lmax[x]=lmax[lson];
if(sum[rson]==r-(mid+1)+1) rmax[x]=sum[rson]+rmax[lson];
else rmax[x]=rmax[rson];
sum[x]=max(max(sum[lson], sum[rson]), rmax[lson]+lmax[rson]);
}
void change(int x, int l, int r, int cl, int cr, int tag){
if(cl<=l&&r<=cr){
if(tag==tag_book) sum[x]=lmax[x]=rmax[x]=0;
else sum[x]=lmax[x]=rmax[x]=r-l+1;
lazy[x]=tag;
return;
}
push_down(x, l, r);
int mid=(l+r)>>1;
if(cl<=mid) change(lson, l, mid, cl, cr, tag);
if(mid<cr) change(rson, mid+1, r, cl, cr, tag);
push_up(x, l, r);
}
int query(int x, int l, int r, int val){
if(l==r) return l;
push_down(x, l, r);
int mid=(l+r)>>1;
if(sum[lson]>=val) return query(lson, l, mid, val);
if(rmax[lson]+lmax[rson]>=val) return mid-rmax[lson]+1;
else return query(rson, mid+1, r, val);
}
void buildt(int x, int l, int r){
if(l==r){
sum[x]=lmax[x]=rmax[x]=1;
return;
}
int mid=(l+r)>>1;
buildt(lson, l, mid);
buildt(rson, mid+1, r);
push_up(x, l, r);
}
int main(){
n=read(),m=read();
buildt(1, 1, n);
while(m--){
int opt=read();
if(opt==1){
int x=read();
if(sum[1]>=x){
int ans=query(1, 1, n, x);
printf("%d\n", ans);
change(1, 1, n, ans, ans+x-1, tag_book);
}else printf("0\n");
}else{
int x=read(),y=read();
change(1, 1, n, x, x+y-1, tag_unbook);
}
}
return 0;
}
[USACO08FEB]酒店Hotel 线段树的更多相关文章
- 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]
题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...
- [USACO08FEB]酒店Hotel 线段树 BZOJ 1593
题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...
- P2894 [USACO08FEB]酒店Hotel 线段树
题目大意 多次操作 查询并修改区间内长度==len的第一次出现位置 修改区间,变为空 思路 类似于求区间最大子段和(应该是这个吧,反正我没做过) 维护区间rt的 从l开始向右的最长长度 从r开始向左的 ...
- 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...
- 浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925
今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记( ...
- 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...
- 洛谷 P2894 [USACO08FEB]酒店Hotel-线段树区间合并(判断找位置,不需要维护端点)+分治
P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultur ...
- P2894 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel 简单的线段树维护区间信息. 维护三个值,一个是从左端点能拓展的长度,一个是从右端点能脱产的的长度.另一个是整个区间内的最大连续零一长度. 记录这三个 ...
- 洛谷 P2894 [USACO08FEB]酒店Hotel 解题报告
P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultur ...
随机推荐
- Python2和3字符编码的区别
Python2和3字符编码的区别 一.字符编码应用之Python 1.1 执行Python程序的三个阶段 Python test.py(我再强调一遍,执行test.py的第一步,一定是先将文件内容从硬 ...
- 小贴士--java篇
1. java: “.”和“|”都是转义字符,必须得加"\\" 2.java :如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu = ...
- 立体像对空间前方交会-共线方程求解法(python实现)
一.原理 二.步骤 a.用各自像片的角元素计算出左右像片的旋转矩阵R1和R2. b.有同名像点列出共线方程. c.将方程写为未知数的线性方程形式,计算线性系数. d.写出误差方程,系数矩阵与常数项. ...
- Vue $emit $event 传值(子to父)
事件名 始终使用 kebab-case 的事件名. 通过事件向父组件发送信息 子组件中EnFontsize.vue中$emit <button @click="$emit('enlar ...
- string类型的解释与方法
基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unico ...
- PHP 的闭包
匿名函数 提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它.声明一个匿名函数是这样: 1 $func = function() { 2 3 }; //带结 ...
- Java反射机制、注解及JPA实现
1.java反射概述 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称 ...
- jenkins中的流水线( pipeline)的理解(未完)
目录 一.理论概述 Jenkins流水线的发展历程 什么是Jenkins流水线 一.理论概述 pipeline是流水线的英文释义,文档中统一称为流水线 Jenkins流水线的发展历程 在Jenki ...
- Docker Compose编排工具部署lnmp实践及理论(详细)
目录 一.理论概述 编排 部署 Compose原理 二.使用docker compose 部署lnmp 三.测试 四.总结 一.理论概述 Docker Compose是一个定义及运行多个Docker容 ...
- Java Data JPA +hibernate 保存或者是查询遇到的坑
由于项目需求,接触了Java Data JPA +hibernate,它的调用方式是controller调用service,service有实现的接口serviceimpl,serviceimpl调用 ...