【[USACO08FEB]酒店Hotel】
比较基础的线段树了
我们要维护最大连续子串,这个可以说是一个比较套路的操作了
我们在[SHOI2009]会场预约这道题中已经比较深刻的认识到了这个套路了
对于这道题,我们显然要知道一个区间内最大的全为1(我的代码里用1表示空房)子串长度是多少,那怎么办呢
我们多开几个数组
\(d[i]\)表示\(i\)这个区间内最大的全为1子串长度
\(rc[i]\)表示\(i\)这个区间内从左端开始的最大全为1子串长度
\(lc[i]\)表示\(i\)这个区间内从右端开始的最大全为1子串长度
于是我们做pushup操作的时候要注意一点,就是某个区间的左端已经全是1,那么\(lc[i]\)要等于左区间长度加上右区间左端的最大全为1子串长度,当然右区间全是1也同理
所以我们这道题就比较好做了
查询的时候自然是先查左区间,如果左区间没有答案,那么我们就再找左右区间中间的部分,即\(rc[i<<1]+lc[i<<1|1]\),如果这个长度大于等于我们要找的长度,我们就可以直接返回了,否则我们再去找右区间
于是就是代码了
#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define maxn 50001
using namespace std;
int l[maxn<<2],r[maxn<<2],tag[maxn<<2],rc[maxn<<2],lc[maxn<<2],d[maxn<<2];
int n,m;
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
inline void pushup(int i)
{
if(d[i<<1]==r[i<<1]-l[i<<1]+1) lc[i]=lc[i<<1]+lc[i<<1|1];
else lc[i]=lc[i<<1];
//这里if的条件最开始写成了d[i<<1]==lc[i<<1],wa了好久,以后看这道题想想为什么
if(d[i<<1|1]==r[i<<1|1]-l[i<<1|1]+1) rc[i]=rc[i<<1|1]+rc[i<<1];
else rc[i]=rc[i<<1|1];
d[i]=max(d[i<<1],max(d[i<<1|1],rc[i<<1]+lc[i<<1|1]));
}
inline void pushdown(int i)
{
if(tag[i]==-1) return;
tag[i<<1]=tag[i];
tag[i<<1|1]=tag[i];
lc[i<<1]=rc[i<<1]=d[i<<1]=(r[i<<1]-l[i<<1]+1)*tag[i];
lc[i<<1|1]=rc[i<<1|1]=d[i<<1|1]=(r[i<<1|1]-l[i<<1|1]+1)*tag[i];
tag[i]=-1;
}
void build(int x,int y,int i)
{
l[i]=x;
r[i]=y;
tag[i]=-1;
if(x==y)
{
rc[i]=lc[i]=d[i]=1;
return;
}
int mid=x+y>>1;
build(x,mid,i<<1);
build(mid+1,y,i<<1|1);
pushup(i);
}
void change(int x,int y,int v,int i)
{
if(x<=l[i]&&y>=r[i])
{
d[i]=lc[i]=rc[i]=(r[i]-l[i]+1)*v;
tag[i]=v;
return;
}
pushdown(i);
int mid=l[i]+r[i]>>1;
if(y<=mid) change(x,y,v,i<<1);
else if(x>mid) change(x,y,v,i<<1|1);
else change(x,y,v,i<<1|1),change(x,y,v,i<<1);
pushup(i);
}
int query(int now,int i)
{
pushdown(i);
int mid=l[i]+r[i]>>1;
if(l[i]==r[i]) return l[i];
if(d[i<<1]>=now) return query(now,i<<1);
if(rc[i<<1]&&rc[i<<1]+lc[i<<1|1]>=now) return (mid-rc[i<<1]+1);
if(d[i<<1|1]>=now) return query(now,i<<1|1);
}
//int ask(int p,int ll,int rr,int length)
//{
// pushdown(p);
// if(ll==rr)return ll;
// int mid=(ll+rr)>>1;
// if(d[p<<1]>=length)return ask(p<<1,ll,mid,length);
// if(rc[p<<1]+lc[p<<1|1]>=length) return mid-rc[p<<1]+1;
// else return ask(p<<1|1,mid+1,rr,length);
// return 0;
//}
int main()
{
n=read();
m=read();
build(1,n,1);
int p,x,y;
while(m--)
{
p=read();
x=read();
if(p==1)
{
int now;
if(d[1]>=x) now=query(x,1);
else now=0;
printf("%d\n",now);
if(now) change(now,now+x-1,0,1);
}
if(p==2) y=read(),change(x,x+y-1,1,1);
}
return 0;
}
【[USACO08FEB]酒店Hotel】的更多相关文章
- 洛谷P2894 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel https://www.luogu.org/problem/show?pid=2894 题目描述 The cows are journeying n ...
- 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...
- 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 ...
- 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel
P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...
- 浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925
今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记( ...
- [USACO08FEB]酒店Hotel 线段树
[USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...
- 洛谷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 ...
- luogu P2894 [USACO08FEB]酒店Hotel
题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...
随机推荐
- Java - 谨慎覆盖clone
覆盖clone时需要实现Cloneable接口,Cloneable并没有定义任何方法. 那Cloneable的意义是什么? 如果一个类实现了Clonable,Object的clone方法就可以返回该对 ...
- IIS网站不能访问
摘要:IIS环境下,部署的网站在服务器上可以正常访问,客户端却不能访问. 原因:防火墙入站规则万维网服务没有开启.
- 实例化geoserver wms服务
var vectorWmsJHdataLayer = new ol.layer.Tile({ source: new ol.source.TileWMS({ //地址 url:'http://loca ...
- ASID 与 MIPS 中 TLB 相关
ASID 为了提高TLB的性能,将TLB分成Global和process-specific.global 是指常驻在tlb中不会被刷出的,例如内核空间的翻译,process-specific 是指每个 ...
- 浅谈WebService之JAX-RS与spring整合
背景:首先谈一下webservice: 1.Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序, 可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发 ...
- mysql Backup &recovery
备份数据库非常重要,这样您就可以恢复数据,并在发生问题时重新启动并运行,例如系统崩溃,硬件故障或用户错误地删除数据. 在升级MySQL安装之前,备份也是必不可少的保护措施,它们可用于将MySQL安装转 ...
- java温故而知新(9)OOP(面向对象编程)理念
Object Oriented Programming (面向对象的程序设计) 1.定义 面向对象程序设计(OOP)的具体定义很难下,也很容易因此而引起争论,在 Object-Orie ...
- 设计模式入门,工厂模式,c++代码实现
// test04.cpp : Defines the entry point for the console application.////设计模式第4章 工厂模式#include "s ...
- 排序算法Nb三人组-归并排序
归并排序只能对两个已经有序的列表进行合并排序,所以要我们自己创建出两个有序列表.最后在进行合并. def merge2list(li1, li2): li = [] i = 0 j = 0 while ...
- class 命名规范
本文是从简书复制的, markdown语法可能有些出入, 想看"正版"和更多内容请关注 简书: 小贤笔记 注: 文章摘自 penggelies07- 简书, super晴天 - C ...