[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. 『Python基础』第7节:基本运算符

    一. 基本运算符 运算按种类可以分为: 算数运算.比较运算.逻辑运算.赋值运算.成员运算.身份运算.位运算. 今天我们只学习算数运算.比较运算.逻辑运算.赋值运算.成员运算 1.1 算数运算 以下假设 ...

  2. rabbitMQ 重试

    rabbitMQ 重试机制 spring.rabbitmq.listener.simple.retry.max-attempts=5 最大重试次数spring.rabbitmq.listener.si ...

  3. SQL Server2008 删除重复记录只剩一条(无Uid)

    INSERT INTO 表1   SELECT  *  FROM  视图1 CREATE TABLE  ##TMP01                                    ---创建 ...

  4. ef core2.2 mysql迁移问题

    前段时间,遇到的是ef core mysql迁移的时候,bool类型会自动yingsheweishort的问题,需要手动更正一下今天测试的时候,遇到了MySQL数据表修改后迁移的问题. 问题详情如下  ...

  5. iOS 中各种横竖屏切换总结

    iOS 中横竖屏切换的功能,在开发iOS app中总能遇到.以前看过几次,感觉简单,但是没有敲过代码实现,最近又碰到了,demo尝试了几种情况,这里就做下总结.注意 横屏两种情况是反的你知道吗? UI ...

  6. Pycharm和Android工具之github使用

    请查看以下链接https://blog.csdn.net/m0_37306360/article/details/79322947 基本操作步骤 打开setting->version contr ...

  7. List集合和Set集合互转

    List集合转成Set集合(如果List集合的元素有重复,转成Set集合就会去掉重复的数据,每条数据只保留一条) //List转化成Set List<String> list = new ...

  8. Linux 之 文件

    文件名称 在linux中,windows概念中的文件夹和文件是没有区别的,都是统称为文件. 1.Linux中文件的名称大小写是敏感的 2.名称最多可以为255个字符 3.除了正斜线以外,都是有效字符 ...

  9. 【OF框架】框架Cache/Session在负载均衡部署时,切换Memory/Redis测试

    一.切换Memory/Redis 第一步:安装运行Redis服务,获得连接参数. 第二步:在appsettings.json中配置 EnableRedisCache 和 Redisconnection ...

  10. Chkdsk /f 修复无法识别EXFAT卷文件系统

    Chkdsk 工具将错误地报告为损坏的 Windows 7 和 Windows Server 2008 R2 中 exFAT 卷文件系统 适用于: Windows Server 2008 R2 Ser ...