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. MySQL事务原理浅析

    前言​ 因为自己对数据的可靠性,可用性方面特别感兴趣,所以在MySQL事务方面看了很多资料,也看了很多博客,所以想到自己也写一篇博客整理整理自己所学内容,尽量用自己的语言解释得通俗易懂. 事务经典场景 ...

  2. 开始Jupyter Notebooks

    开始Jupyter Notebooks 安装Anaconda 因为不能有空格,所以没有选C:\Program Files 认识Jupyter Notebooks 修改 jupyter notebook ...

  3. Thread interrupted() 线程的中断

    问题: 1.线程的中断方式. 2.为什么中断阻塞中的线程,会抛出异常. 代码示例: package com.hdwl.netty; public class ThreadInterrupted { p ...

  4. hdu 2539 虽然是水题 wa了很多次 说明自己的基本功不扎实 需要打好基础先 少年

    两点吧 1.gets使用的时候 确保上一次的回车符对其没有影响 getline也是如此 这样的细节..  多注意啊!! 2.编写程序的时候 对一些极端的情况要多调试 比如此题当 n==1的时候..  ...

  5. 火狐浏览器 访问所有HTTPS网站显示连接不安全解决办法

    当 Firefox 连接到一个安全的网站时(网址最开始为“https://”),它必须确认该网站出具的证书有效且使用足够高的加密强度.如果证书无法通过验证,或加密强度过低,Firefox 会中止连接到 ...

  6. Bootstrap4 入门

    http://www.runoob.com/bootstrap4/bootstrap4-navs.html 共五个部分 1 <!DOCTYPE html> <html lang=&q ...

  7. C#倒计时关闭提示框

    前两天实现某个功能需要做一个提示框 并且能够自动关闭的,就从网上搜了一个能够自动关闭的提示框 ,但由于我需要的场景是不确定计时时间的,所以并没有使用到该窗体,但是我觉得可以留存备用 ,后边也把我 这种 ...

  8. 本地数据存储解决方案以及cookie的坑

    本地数据存储解决方案以及cookie的坑 问题: cookie过长导致页面打开失败 背景: 在公司的项目中有一个需求是打开多个工单即在同一个页面中打开了多个tab(iframe),但是需要在刷新时只刷 ...

  9. Innodb学习

    一.并发控制 为什么要进行并发控制? 因为并发的任务会对同一个临界资源进行操作,如果不进行并发控制,可能导致不一致,故必须进行并发控制. 如何进行并发控制? 1.锁. 2.数据多版本. 施工ing.. ...

  10. Android笔记(十六) 简易计算器

    实现功能: 简单计算器 布局及美化 采用LinearLayout嵌套LinearLayout实现布局. 要求 1. 按钮所有文字居于右下角 2. 按钮为白色,点击变成橘色 3. 显示屏文字居右显示并且 ...