比较基础的线段树了

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

我们在[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. ASP.NET MVC4 新手入门教程之六 ---6.编辑视图与编辑方法

    在本节中,您会为电影控制器检查生成的操作方法和视图.然后,您将添加一个自定义的搜索页面. 运行该应用程序,然后浏览到Movies控制器通过将/Movies追加到您的浏览器的地址栏中的 URL.将鼠标指 ...

  2. Grunt项目构建-插件学习

    听说过Grunt也有两年了,用了也有两年了,然而都是在别人搭好的架子上做开发,当想要对前端工程化整体把控时就一脸懵逼了! Grunt是什么? Grunt是一套web前端工程化构建工具.(ps:关于Gr ...

  3. Azure Java Libraries 入门

    本指南演示了以下 Azure Java Libraries 的用法,包括设置认证.创建并使用 Azure 存储.创建并使用 Azure SQL 数据库.部署虚拟机.从 GitHub 部署 Azure ...

  4. @media print样式 关于table断页

    <html> <head> <style> @media print { table { page-break-after:auto } tr { page-bre ...

  5. ccf-201609-2 火车购票

    问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排5个座位.为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10 ...

  6. 一道google的面试题(据说)

    1. 原题(同事给的) Max Howell 参加了谷歌的面试,出题人竟然要求 Max Howell 在白板上作出解答,Max Howell 当然愤怒地拒绝了,回家以后马上在微博上跟我们分享他的吐槽: ...

  7. jquery each() 方法跳出循环

    1.jquery each() 方法  return false: 的时候  相当于  break; 跳出整个循环: 2.jquery each() 方法  return true: 的时候  相当于 ...

  8. ueditor默认字体和字号修改

    ueditor编辑器默认字号是16号,默认字体为sans-serif,显得有些难看,所以决定修改默认值.配置文件ueditor.config.js可以修改整个编辑器配置项,里面有配置项fontfami ...

  9. 学习C++从入门到精通的的十本最经典书籍

    原文:http://blog.csdn.net/a_302/article/details/17558369 最近想学C++,找了一下网上推荐的书籍,转载过来给大家分享 转载自http://c.chi ...

  10. 【Python】Sublime text 3 搭建Python IDE

    背景: 最经遇到一件很苦恼的事情,就是在Sublime text 3中写的Python代码直接挪到python原生的ide中老是报格式的错误(有时让人讨厌的缩进),没有办法,看到Sublime tex ...