[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 ...
随机推荐
- Hadoop 完全分布式搭建
搭建环境 https://www.cnblogs.com/YuanWeiBlogger/p/11456623.html 修改主机名------------------- 1./etc/hostname ...
- Oracle通过ODBC链接SqlServer数据库
原网址:https://www.cnblogs.com/jijm123/p/11598515.html 第一步.创建ODBC数据源 这一步要考虑数据源是32位还是64位的问题,其实就是选择不同的exe ...
- Qt界面阴影效果(背景图片)
实现原理: 1.顶层窗体设置为无边框,背景半透明 2.顶层窗体的子窗体使用带有阴影的图片做背景 代码: //CMainWindow.h#ifndef CMAINWINDOW_H#define CMAI ...
- Jquery DataTables 服务器后端分页 Ajax请求添加自定义参数.
项目使用AdminLTE(基于Bootstrap 二次开发的框架)作为开发框架. 使用DataTables 的时候部分页面需要传参 给后台做筛选过滤. 但是不知道怎么将DataTables的参数 和自 ...
- NRF52832 Mesh调试,使其同时支持串口打印和RTT打印
查看开发环境里面,是否有这个文件,如果没有你的话,则添加文件. 然后要在sdk_config.h中添加使能 然后打开刚才添加的文件retarget.c,主意里面这些地方 这里它进行判断,要么使用RTT ...
- C++开源库大全
标准库 C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Template Library:标准模板库 ...
- for_each使用方法详解
for_each使用方法详解[转] Abstract之前在(原創) 如何使用for_each() algorithm? (C/C++) (STL)曾經討論過for_each(),不過當時功力尚淺, ...
- Element ui tree 搜索
搜索框 属性 :filter-node-method="filterNode" 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点 ...
- putty使用方法
putty是一种体体积小,无需安装的一款免费安全使用方便的绿色软件,它主要用于远程控制linux系统,只要获取了远程的linux的地址,便可以远程控制linux系统以方便管理,越来越受到各方面的欢迎. ...
- 【vue开发】超简单的防止连续点击js指令方法
vue防重复点击(指令实现) 快速点击按钮会重复多次调用接口,防止出现这样的情况 全局定义,方便调用 新建plugins.js export default { install (Vue) { // ...