比较基础的线段树了

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

我们在[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. linux 查看某几行内容与文件分割

    查看指定行数 sed -n 4,8p file #打印file中的4-8行 sed -n 4p file #打印file中的第4行 grep ^pw file # 查看file中以pw开头的行 在Li ...

  2. Sequence contains no elements : LINQ error

    1.错误意思: 出现错误的原因是:你要从一个null中取的数据. 2.错误的处理 1,使用FirstOrDefault() 来代替 First() 2.使用SingleOrDefault 来代替 Si ...

  3. 六、Spring之DI的Bean的作用域

    Spring提供“singleton”和“prototype”两种基本作用域,另外提供“request”.“session”.“global session”三种web作用域:Spring还允许用户定 ...

  4. python os.popen 乱码问题

    os.popen('ipconfig') 命令返回的结果在调试时乱码了: output1 = os.popen('ipconfig') o1=output1.read() 我猜这里输出的内容要和控制台 ...

  5. C Primer Plus note3

    上面的源代码为什么输入q的时候,程序就会退出呢? while(条件语句),status == 1是条件语句,status只要是非0值的时候,status == 1的条件就满足,程序就会运行while循 ...

  6. 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...

  7. content-box跟border-box的区别

    content-box: padding和border不被包含在定义的width和height之内.对象的实际宽度等于设置的width值和border.padding之和,即 ( Element wi ...

  8. RoadFlow工作流与JUI(DWZ)前端框架的集成

    此文只说明RoadFlow前端与JUI的集成,关于程序和接口请参照WebForm或MVC文档. 修改JUI配置文件dwz.frag.xml,此文件一般位于JUI根目录下. 2.修改文件js/dwz.n ...

  9. Jave 之方法-函数(5)

    如何定义Java中的方法: 所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块. (方法在C语言中被称为函数) 一般情况下,定义一个方法的语法是: 其中: 1. 访问修饰符:方法允许被访问 ...

  10. 11_Redis集群

    [Redis集群分类] 1.主从复制(master/slave) 2.高可用Sentinel哨兵 3.高可用集群模式 [ 主从复制(master/slave)] [Redis一主多从架构] 通过持久化 ...