[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 线段树的更多相关文章

  1. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  2. [USACO08FEB]酒店Hotel 线段树 BZOJ 1593

    题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  3. P2894 [USACO08FEB]酒店Hotel 线段树

    题目大意 多次操作 查询并修改区间内长度==len的第一次出现位置 修改区间,变为空 思路 类似于求区间最大子段和(应该是这个吧,反正我没做过) 维护区间rt的 从l开始向右的最长长度 从r开始向左的 ...

  4. 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel

    题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...

  5. 浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925

    今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记( ...

  6. 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...

  7. 洛谷 P2894 [USACO08FEB]酒店Hotel-线段树区间合并(判断找位置,不需要维护端点)+分治

    P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultur ...

  8. P2894 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel 简单的线段树维护区间信息. 维护三个值,一个是从左端点能拓展的长度,一个是从右端点能脱产的的长度.另一个是整个区间内的最大连续零一长度. 记录这三个 ...

  9. 洛谷 P2894 [USACO08FEB]酒店Hotel 解题报告

    P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultur ...

随机推荐

  1. Hadoop 完全分布式搭建

    搭建环境 https://www.cnblogs.com/YuanWeiBlogger/p/11456623.html 修改主机名------------------- 1./etc/hostname ...

  2. Oracle通过ODBC链接SqlServer数据库

    原网址:https://www.cnblogs.com/jijm123/p/11598515.html 第一步.创建ODBC数据源 这一步要考虑数据源是32位还是64位的问题,其实就是选择不同的exe ...

  3. Qt界面阴影效果(背景图片)

    实现原理: 1.顶层窗体设置为无边框,背景半透明 2.顶层窗体的子窗体使用带有阴影的图片做背景 代码: //CMainWindow.h#ifndef CMAINWINDOW_H#define CMAI ...

  4. Jquery DataTables 服务器后端分页 Ajax请求添加自定义参数.

    项目使用AdminLTE(基于Bootstrap 二次开发的框架)作为开发框架. 使用DataTables 的时候部分页面需要传参 给后台做筛选过滤. 但是不知道怎么将DataTables的参数 和自 ...

  5. NRF52832 Mesh调试,使其同时支持串口打印和RTT打印

    查看开发环境里面,是否有这个文件,如果没有你的话,则添加文件. 然后要在sdk_config.h中添加使能 然后打开刚才添加的文件retarget.c,主意里面这些地方 这里它进行判断,要么使用RTT ...

  6. C++开源库大全

        标准库 C++ Standard Library:是一系列类和函数的集合,使用核心语言编写,也是C++ISO自身标准的一部分. Standard Template Library:标准模板库 ...

  7. for_each使用方法详解

    for_each使用方法详解[转]   Abstract之前在(原創) 如何使用for_each() algorithm? (C/C++) (STL)曾經討論過for_each(),不過當時功力尚淺, ...

  8. Element ui tree 搜索

    搜索框 属性 :filter-node-method="filterNode" 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点 ...

  9. putty使用方法

    putty是一种体体积小,无需安装的一款免费安全使用方便的绿色软件,它主要用于远程控制linux系统,只要获取了远程的linux的地址,便可以远程控制linux系统以方便管理,越来越受到各方面的欢迎. ...

  10. 【vue开发】超简单的防止连续点击js指令方法

    vue防重复点击(指令实现) 快速点击按钮会重复多次调用接口,防止出现这样的情况 全局定义,方便调用 新建plugins.js export default { install (Vue) { // ...