【[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 ...
随机推荐
- python-入门教程(操作mysql数据库)
pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x,而MySQLdb不支持3.x版本. 本文测试python版本:3.6. ...
- C#基本语法 - .Net 4.0 之 Dynamic 动态类型
一..net4.0主要新特性 .Net4.0在.Net3.5基础上新增的主要特性有:可选参数.命名参数和Dynamic.具体请阅生鱼片的这篇博文.这里我们着重讲解C#4.0的Dynamic特性,对 ...
- C#,动态加载DLL,通过反射,调用参数,方法,窗体
.net中常会用到动态加载DLL,而DLL中可能包含各种参数.方法.窗体,如何来调用动态加载这些参数.方法.窗体呢? 在C#中,我们要使用反射,首先要搞清楚以下命名空间中几个类的关系: System. ...
- 深入浅出ConcurrentHashMap1.8
转载:https://www.jianshu.com/p/c0642afe03e0 好文 关于文章中的疑问:为什么要构造一个反序链表,放在nextTable的i+n的位置上呢,在<深入分析Con ...
- js为什么放到head中有时候失效
1.今天写js碰到一个奇怪的问题,写好的js放到body里面执行,但是放到head中没有任何效果,为什么导致这种原因呢? 看失效代码: <!DOCTYPE html PUBLIC "- ...
- Python-并发编程(进程)
接下来我们用几天的时间说一说python中并发编程的知识 一.背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作 ...
- js和jq获取宽度和高度
Javascript: console.log(document.body.clientWidth); //网页可见区域宽(body) console.log(document.body.client ...
- node定时任务
var schedule = require('node-schedule') require('shelljs/global'); function scheduleCronstyle(){ sch ...
- MySQL性能优化的20+条经验
1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一 ...
- 形象解释C#、Net、Asp.net
下文是写给计算机小白的,尽量用形象的语言来让她们明白这些比较抽象的概念. -------------------------------------- C#: 你和美国人说话要说英语 和中国人说话说汉 ...