C. Hotel 旅馆

内存限制:256 MiB 时间限制:1000 ms 标准输入输出
题目类型:传统 评测方式:文本比较
 

题目描述

OIER最近的旅游计划,是到长春净月潭,享受那里的湖光山色,以及明媚的阳光。作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿。这个巨大的旅馆一共有N

间客房,它们在同一层楼中顺次一字排开,在任何一个房间里,只需要拉开窗帘,就能见到波光粼粼的湖面。 所有的旅游者,都是一批批地来到旅馆的服务台,希望能订到 间连续的房间。服务台的接待工作也很简单:如果存在r满足编号为 的房间均空着,他就将这一批顾客安排到这些房间入住;如果没有满足条件的r,他会道歉说没有足够的空房间,请顾客们另找一家宾馆。如果有多个满足条件的r,服务员会选择其中最小的一个。 旅馆中的退房服务也是批量进行的。每一个退房请求由2个数字 、 描述,表示编号为 房间中的客人全部离开。退房前,请求退掉的房间中的一些,甚至是所有,可能本来就无人入住。 而你的工作,就是写一个程序,帮服务员为旅客安排房间。你的程序一共需要处理

个按输入次序到来的住店或退房的请求。第一个请求到来前,旅店中所有房间都是空闲的。

输入格式

第1行: 2个用空格隔开的整数:N、M

第2..M+1行: 第i+1描述了第i个请求,如果它是一个订房请求,则用2个数字 1、

描述,数字间用空格隔开;如果它是一个退房请求,用3 个以空格隔开的数字

、 、 描述

输出格式

第1..??行: 对于每个订房请求,输出1个独占1行的数字:如果请求能被满足 ,输出满足条件的最小的r;如果请求无法被满足,输出0

样例

样例输入

10 6
1 3
1 3
1 3
1 3
2 5 5
1 6

样例输出

1
4
7
0
5


线段树区间合并裸题 我们设这样几个数组 : max_near、max_l、max_r、lazy来分别表示区间最大连续长度,从左开始的最大连续长度,从右开始的区间最大连续长度、懒度标记 
 
这样 我们的max_near就是max(max(max_near[lc],max_near[rc]),max_r[lc]+max_r[lc]) 对于max_l的维护,若左儿子的max_next等于len,那么就是左儿子的len加右儿子max_l,否则是左儿子的max_l,max_r类似。
 
对于每次查询,如果max_near[root] < query ,那么直接输出0即可,否则的话以 左子树? 左子树右加右子树左 ? 右子树的顺序选择递归,返回ans并从ans+query的区间范围对树进行修改。


代码:
#include<bits/stdc++.h>
#define re register int
using namespace std;
int n,m,o;
int a,d,x,maxx;
int max_near[500100],max_l[500100],max_r[500100],len[500100],lazy[500100],cl[500100],cr[500100];
void pp(int k)
{
    max_l[k]=max_l[k<<1];
    max_r[k]=max_r[k<<1|1];
    if(max_l[k]==(cr[k<<1]-cl[k<<1]+1))
        max_l[k]+=max_l[k<<1|1];
    if(max_r[k]==(cr[k<<1|1]-cl[k<<1|1]+1))
        max_r[k]+=max_r[k<<1];
    max_near[k]=max(max_r[k<<1]+max_l[k<<1|1],max(max_near[k<<1],max_near[k<<1|1]));
    
    /*
        错误搞法
    len[k]=len[k<<1]+len[k<<1|1];
    
    max_l[k]=(max_near[k<<1]==len[k<<1])?(len[k<<1]+max_l[k<<1|1]):max_l[k<<1];
    
    max_r[k]=(max_near[k<<1|1]==len[k<<1|1])?(len[k<<1|1]+max_r[k<<1]):max_r[k<<1|1];
    max_near[k]=max_r[k<<1]+max_l[k<<1|1];
    
    */
    return;
}
void build(int k,int l,int r)
{
    cl[k]=l;
    cr[k]=r;
    lazy[k]=-1;
    if(l==r)
    {
        max_l[k]=max_r[k]=max_near[k]=len[k]=1;
        return;
    }
    int m=(l+r)>>1;
    build(k<<1,l,m);
    build(k<<1|1,m+1,r);
    pp(k);
}
void pushdown(int r,int lc,int rc)
{
    if(lazy[r]!=-1)
    {
        lazy[lc]=lazy[rc]=lazy[r];
        if(lazy[r])
        {
            max_near[lc]=max_l[lc]=max_r[lc]=len[lc]=0;
            max_near[rc]=max_l[rc]=max_r[rc]=len[rc]=0;
        }
        else
        {
            max_near[lc]=max_l[lc]=max_r[lc]=len[lc]=cr[lc]-cl[lc]+1;
            max_near[rc]=max_l[rc]=max_r[rc]=len[rc]=cr[rc]-cl[rc]+1;
        }
        lazy[r]=-1;
    }
}
int que(int k,int d)
{
    int m=(cl[k]+cr[k])>>1;
    if(cl[k]==cr[k])
        return cl[k];
    /*    
        错误,因为开端不一定在最左边!
        if(max_near[k]==d)
        return cl[k];
    */
    pushdown(k,k<<1,k<<1|1);
    if(max_near[k<<1]>=d)
        return    que(k<<1,d);
     if(max_r[k<<1]+max_l[k<<1|1]>=d)  
        return m-max_r[k<<1]+1;
    else
        return que(k<<1|1,d);
}

void updata(int l,int r,int root,int z)
{
    if(l<=cl[root]&&cr[root]<=r)
    {
        lazy[root]=z;
        if(z)
            max_near[root]=max_l[root]=max_r[root]=len[root]=0;
        else
            max_near[root]=max_l[root]=max_r[root]=len[root]=cr[root]-cl[root]+1;
        return;
    }
    int m=(cr[root]+cl[root])>>1;
    pushdown(root,root<<1,root<<1|1);
    if(m>=l)
        updata(l,r,root<<1,z);
    if(m<r)
        updata(l,r,root<<1|1,z);
    pp(root);
}
int qian(int x)
{
    if(cl[x<<1])
        qian(x<<1);
    if(cl[x<<1|1])
        qian(x<<1|1);
}
int main()
{
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(re i=1;i<=m;i++)
    {
        scanf("%d",&a);
        if(a==1)
        {
            scanf("%d",&d);
            if(max_near[1]<d)
            {
                printf("0\n");
                continue;
            }
            o=que(1,d);
            printf("%d\n",o);
            updata(o,o+d-1,1,1);
        }
        else
        {
            scanf("%d%d",&x,&d);
            updata(x,x+d-1,1,0);
        }
    }
    return 0;
}

Hotel 旅馆, 线段树查询,合并的更多相关文章

  1. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

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

  2. Poj 3667——hotel——————【线段树区间合并】

    Hotel Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13124   Accepted: 5664 Descriptio ...

  3. poj3667 Hotel (线段树 区间合并)

    poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...

  4. poj 3667 Hotel (线段树的合并操作)

    Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  5. POJ 3667 Hotel(线段树+区间合并)

    http://poj.org/problem?id=3667 题意: 有N个房间,M次操作.有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示 ...

  6. BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆 [线段树]

    传送门 题意: 操作1:找长为$len$的空区间并填满,没有输出$0$ 操作2:将$[l,r]$之间的区间置空 我真是太弱了这种线段树还写了一个半小时,中间为了查错手动模拟了$30min$线段树操作, ...

  7. bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 758  Solved: 419[Submit ...

  8. POJ 3667 Hotel (线段树区间合并)

    题目链接:http://poj.org/problem?id=3667 题目大意:一共有n个房间,初始时都是空的,现在有m个操作,操作有以下两种: 1.1 d :询问是否有连续d个空的房间,若有则输出 ...

  9. (简单) POJ 3667 Hotel,线段树+区间合并。

    Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...

随机推荐

  1. AJAX异步原理与实现

    面试时问到了这个问题,说实话我还是不理解的,只是单单会使用.所以今天我看一下,自己了解下. 看了网上前辈们写的资料,我自己总结归纳ajax的原理和流程如下: 1.AJAX创建异步对象XMLHttpRe ...

  2. 让Qt5默认支持C++17的设置方法

    单个项目的设置方法 打开项目的 pro 文件,将CONFIG += console c++11改为CONFIG += console c++17即可. 永久默认支持 c++17 的设置方法 找到 Qt ...

  3. 永恒之蓝MS17-010漏洞复现

    永恒之蓝MS17-010漏洞复现 1.漏洞描述: 起因: 永恒之蓝(Eternalblue)是指2017年4月14日晚,黑客团体Shadow Brokers(影子经纪人)公布一大批网络攻击工具,其中包 ...

  4. 我是怎么写 Git Commit message 的?

    目录 作用 用的什么规范? type scope subject body footer 参考文章 用的什么辅助工具? 作用 编写格式化的 commit message 能够大大提高代码的维护效率. ...

  5. 解决git同步每次都需要输入用户名、密码

    打开 git bash 执行命令: git config --global credential.helper store

  6. web自动化页面元素不能键盘输入

    一.背景 web自动化中存在一部分元素属性是readonly属性,导致我们在使用自动化代码的时候无法使用sendkeys()方法传入数据,以12306网站选择出发日期为例,见下图 二.json语句处理 ...

  7. Pandas高级教程之:GroupBy用法

    Pandas高级教程之:GroupBy用法 目录 简介 分割数据 多index get_group dropna groups属性 index的层级 group的遍历 聚合操作 通用聚合方法 同时使用 ...

  8. java:编写jar包加密工具,防止反编译

    懒人方案 网盘: 链接:https://pan.baidu.com/s/1x4OB1IF2HZGgtLhd1Kr_AQ提取码:glx7 网盘内是已生成可用工具,下载可以直接使用,使用前看一下READ. ...

  9. buu 不一样的flag

    一.查壳 二.拖入ida,分析 从这里和51到53行的代码,基本判断这是一个迷宫题,并且是5行5列的一个迷宫.我当时感觉到一个奇怪的地方是 第一个,我自己想明白是因为可能是int型,数字占了4个字节, ...

  10. 一文读懂 .NET 中的高性能队列 Channel

    介绍 System.Threading.Channels 是.NET Core 3.0 后推出的新的集合类型, 具有异步API,高性能,线程安全等特点,它可以用来做消息队列,进行数据的生产和消费, 公 ...