比较基础的线段树了

我们要维护最大连续子串,这个可以说是一个比较套路的操作了

我们在[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】的更多相关文章

  1. 洛谷P2894 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel https://www.luogu.org/problem/show?pid=2894 题目描述 The cows are journeying n ...

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

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

  3. P2894 [USACO08FEB]酒店Hotel

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

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

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

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

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

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

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

  7. [USACO08FEB]酒店Hotel 线段树

    [USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...

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

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

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

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

  10. luogu P2894 [USACO08FEB]酒店Hotel

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

随机推荐

  1. Spring初始化日志

    Spring启动时的日志: 2013-11-22 14:55:59:319[INFO]: FrameworkServlet 'spring3': initialization completed in ...

  2. JavaScript中变量声明以及数据类型

    JavaScript变量 变量名必须以字母或下划线("_")开头 变量也能以 $ 和 _ 符号开头(不过我们不推荐这么做) 变量名称对大小写敏感(y 和 Y 是不同的变量) 变量可 ...

  3. visual studio 安装与sqlserver 安装

    先sqlserver再visual studio ,避免安装目录重复(sqlserver 中包含一部分visual  而  visual studio 中也包含有部分sqlserver内容) 安装vi ...

  4. Linux下剪切拷贝命令

    Linux下剪切拷贝命令   命令格式: mv   source    dest   mv: 命令字   source: 源文件   dest: 目的地址   Linux下拷贝命令   命令格式:cp ...

  5. css3之弹性盒模型初探(一)

    什么是弹性盒模型? 弹性盒模型是指在父级改变大小的时候内部的自己元素也会相应的改变大小,即子集会按照父级的大小按比例自适应大小. 弹性盒模型的提出可以解决一些响应式布局的需求   如何使用弹性盒模型? ...

  6. csharp:using Newtonsoft.Json.Net2.0 in .net 2.0 webform

    /// <summary> /// http://www.weather.com.cn/data/sk/101280601.html /// {"weatherinfo" ...

  7. Python-并发编程(协程)

    今天说说协程 一.引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两 ...

  8. Web前端面试指导(十九):CSS样式-如何清除元素浮动?

    题目点评 本题属于比较常问的题目,也是在网页设计中经常遇到的问题,面试官希望通过这样的面试题来了解你对网页设计的基本功底,如果这样的题目答不出来,必会让面试官大失所望,面试成功的概率是非常小的. 答题 ...

  9. 浅谈PVC塑料配方计算软件的设计

    1, 配方设计与配方计算 题目是配方计算,不是配方设计,设计是需要有深厚的塑料知识才可以做的,即生产什么塑料产品,需要放各种原料是什么,各自比较是多少,遇到什么情况下就要多放什么,少放什么.配方设计不 ...

  10. icon-font 字体图标的引用

    1.font-class引用 font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题. 与unicode使用方式相比,具有如下特点: 兼容性良好, ...