https://www.luogu.org/problem/P2894

#include<cstdio>
#include<iostream>
using namespace std;
struct ben
{
int lmax,rmax,len,sum,lz;
}tr[400005];
void bt(int x,int l,int r)//建树
{
tr[x].lz=0;//标记清空
tr[x].sum=tr[x].len=tr[x].lmax=tr[x].rmax=r-l+1;//区间连续,区间长度,左端点连续,右端点连续都初始化成区间的长度。(因为所有房间都是空的
if(l==r)//如果到了叶子节点
{
return ;//返回
}
int mid=(l+r)/2;
bt(x*2,l,mid);
bt(x*2+1,mid+1,r);
//左右建子节点
}
void down(int x)//标记下放
{
if(tr[x].lz==0)return ;//如果没有标记,直接返回
if(tr[x].lz==1)//如果是要开房
{
tr[x*2].lz=tr[x*2+1].lz=1;//左右子节点都要标记上开房
tr[x*2].rmax=tr[x*2].lmax=tr[x*2].sum=0;
tr[x*2+1].rmax=tr[x*2+1].lmax=tr[x*2+1].sum=0;
//左右子节点因为已经开房而没有空房都变成0
}
if(tr[x].lz==2)//如果要退房
{
tr[x*2].lz=tr[x*2+1].lz=2;////左右子节点都要标记上退房
tr[x*2].rmax=tr[x*2].lmax=tr[x*2].sum=tr[x*2].len;
tr[x*2+1].rmax=tr[x*2+1].lmax=tr[x*2+1].sum=tr[x*2+1].len;
//此区间已经全为空房,所有直接都等于len即可
}
tr[x].lz=0;//要把父节点的标记清空
}
void renew(int x)//更新节点信息
{
if(tr[x*2].sum==tr[x*2].len)//如果左子节点全为空房
{
tr[x].lmax=tr[x*2].sum+tr[x*2+1].lmax;//那么父节点的左端最大连续为左子区间加上右子区间从左的最大连续
}
else
{
tr[x].lmax=tr[x*2].lmax;//否则就是沿用左从左
}
if(tr[x*2+1].sum==tr[x*2+1].len)//右边同理
{
tr[x].rmax=tr[x*2+1].sum+tr[x*2].rmax; }
else
{
tr[x].rmax=tr[x*2+1].rmax;
}
tr[x].sum=max(max(tr[x*2].sum,tr[x*2+1].sum),tr[x*2].rmax+tr[x*2+1].lmax);//最大连续的是左区间或右区间或左+右中最大的
}
void change_interval(int x,int l,int r,int tag,int L,int R)//区间修改,tag=1表示开房,tag=2表示退房
{
down(x);//下放懒标记
if(L<=l&&r<=R)//当前要查`询的区间如果在区间内
{
if(tag==1)
{
tr[x].sum=tr[x].lmax=tr[x].rmax=0;//开房就没有连续
}
else
{
tr[x].sum=tr[x].lmax=tr[x].rmax=tr[x].len;//退房就全是连续
}
tr[x].lz=tag;//打个懒标记
return ; //别忘返回,因为在整个查询区间内
}
int mid=(l+r)/2;
if(L<=mid)change_interval(x*2,l,mid,tag,L,R);
if(R>mid)change_interval(x*2+1,mid+1,r,tag,L,R);
renew(x);//更新当前节点 信息
}
int ask(int x,int l,int r,int ans)//查询有没有那么多连续的空房间
{
down(x);//下放懒标记
if(l==r)return l;//到叶子了,直接反回
int mid=(l+r)/2;
if(tr[x*2].sum>=ans)return ask(x*2,l,mid,ans);//如果左边就够用了 ,那么去左边找 (不要忘了是return !!!!!!!
if(tr[x*2].rmax+tr[x*2+1].lmax>=ans)return mid-tr[x*2].rmax+1;//否则左+右够了,那么就找左加右那个端点
return ask(x*2+1,mid+1,r,ans);//再否则就只能在右区间找了
}
int main()
{
int n,m,opt,x,y;
scanf("%d%d",&n,&m);
bt(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&opt,&x);
if(opt==1)
{
if(tr[1].sum>=x)
{
int left=ask(1,1,n,x);
printf("%d\n",left);
change_interval(1,1,n,1,left,left+x-1);
}
else
{
printf("0\n");
}
}
else
{
scanf("%d",&y);
change_interval(1,1,n,2,x,x+y-1);
}
}
return 0;
}

区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel的更多相关文章

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

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

  2. 洛谷P2894 [USACO08FEB]酒店Hotel

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

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

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

  4. 洛谷P2894[USACO08FEB]酒店Hotel(线段树)

    问题描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  5. 洛谷 P2894 [USACO08FEB]酒店Hotel

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

  6. 洛谷 P2894 [USACO08FEB]酒店Hotel-线段树区间合并(判断找位置,不需要维护端点)+分治

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

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

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

  8. 洛谷 P2894 [USACO08FEB]酒店

    题目描述 用线段树维护三个值:区间最长空位长度,从左端点可以延伸的最长空位长度,从右端点可以延伸的最长空位长度. #include<complex> #include<cstdio& ...

  9. 洛谷P2894 [USACO08FEB]酒店Hotel_区间更新_区间查询

    Code: #include<cstdio> #include<algorithm> #include<cstring> using namespace std; ...

随机推荐

  1. 【springcloud】2.eureka源码分析之令牌桶-限流算法

    国际惯例原理图 代码实现 package Thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomi ...

  2. Python yield 使用浅析【转】

    Python yield 使用浅析 IBM developerWorks 中国 : Open source IBM 开源 - IBM Developer 中国 (原 developerWorks 中国 ...

  3. windows下mysql表名区分大小写

    windows下mysql默认是不区分大小写的,但是linux会区分大小写 如何让windows下mysql区分大小写呢? 修改 my.ini 里面的mysqld部分 #区分大小写 lower_cas ...

  4. Go 操作 Mysql(二)

    查询数据方法回顾整理 上一篇博客中,主要是快速过了一遍 demo 代码和 DB 类型对象中方法的使用 在整理查询数据方法的时候,使用了 Query() 方法,其实 sqlx 还提供了 QueryRow ...

  5. js入门之内置数组对象 Array

    一. 数组 1. 创建数组的两种方式 1. 数组字面量 var array = [] 2. 数组的构造函数创建数组 var array = new Array(); 2. 如何判断一个变量是否是数组 ...

  6. vue 做的tabBar组件

    效果如下 调用 <tabbar :selected='selected'></tabbar> 组件 <template> <div class='tabbar ...

  7. Java 之 字节流

    一.一切皆为字节 一切文件数据(文本.图片.视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此.所以,字节流可以传输任意文件数据.在操作流的时候,我们要时刻明确,无论使 ...

  8. csv注入复现代码

    以下代码生成的csv文件,使用Microsoft Execl能成功弹出计算器,虽然打开时有安全提示,但是大多数src还是会接收该类漏洞 -------------------------------- ...

  9. stm32 CAN通信 TJA1040

    CAN协议特点 1.多主控制 所有单元都可以发送消息,根据标识符(Identifier简称ID)决定优先级.仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工 ...

  10. HTML和XML中的转义字符

    HTML中的转义字符  HTML中<, >,&等有特别含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用他们的转义序列,如下所示: & ...