题意:有两种操作

1,从左往右找一个区间是 D 的连续序列,然后覆盖,返回区间最前面的数,如果没有输出0
2, 释放从L开始连续D的区间
分析:就是从左往右查找一个D的连续区间,可以使用三个值操作lsum,rsum,sum,分别是从左往右的最大连续值,从右往左的最大连续值,整个区间的最大连续区间,与(I - Tunnel Warfare - hdu 1540)有些类似,不过更新时候是不一样的,这个sum单纯的保存最大连续区间
***********************************************************************
#include<algorithm>
#include<stdio.h>
using namespace std; #define lson r<<1
#define rson r<<1|1 const int MAXN = 1e5+; struct segmentTree
{///分别代表左边的最大连续区间,右边的最大连续区间,最大连续区间
    int L, R, lsum, rsum, sum;
    int op;///op等于 0 的时候不操作,等于 1 的时候房间占用,2 释放
    int len(){return R-L+;}
    int mid(){return (L+R)>>;}
}a[MAXN<<]; void pushDown(int r)
{
    if(a[r].L != a[r].R && a[r].op)
    {
        a[lson].lsum = a[lson].rsum = a[lson].sum = (a[r].op ==  ?  : a[lson].len());
        a[rson].lsum = a[rson].rsum = a[rson].sum = (a[r].op ==  ?  : a[rson].len());         a[lson].op = a[rson].op = a[r].op;
        a[r].op = ;
    }
}
void pushUp(int r)
{///一定要注意先把上层更新,才能进行合并操作
    a[r].lsum = a[lson].lsum, a[r].rsum = a[rson].rsum;     if(a[lson].lsum == a[lson].len())
        a[r].lsum += a[rson].lsum;
    if(a[rson].rsum == a[rson].len())
        a[r].rsum += a[lson].rsum;     a[r].sum = max(a[lson].sum, max(a[rson].sum, a[lson].rsum+a[rson].lsum));
}
void Build(int r, int L, int R)
{
    a[r].L = L, a[r].R = R, a[r].op = ;
    a[r].lsum = a[r].rsum = a[r].sum = a[r].len();     if(L == R)return ;     Build(lson, L, a[r].mid());
    Build(rson, a[r].mid()+, R);
}
void upDate(int r, int L, int R, int op)
{
    if(a[r].L==L && a[r].R==R)
    {///等于1房间完全被占用,那么剩余就是0,否则全部释放
        a[r].lsum=a[r].rsum=a[r].sum = (op==?  : a[r].len());
        a[r].op = op;         return ;
    }
    pushDown(r);     if(R <= a[r].mid())
        upDate(lson, L, R, op);
    else if(L > a[r].mid())
        upDate(rson, L, R, op);
    else
    {
        upDate(lson, L, a[r].mid(), op);
        upDate(rson, a[r].mid()+, R, op);
    }     pushUp(r);///向上更新父节点,只有下层改变值得时候需要这个操作
}
int  Query(int r, int e)
{///判断原则,从左往右,找到最靠左的能够放下e的连续区间     pushDown(r);     if( a[r].lsum >= e)return a[r].L;///判断最前面是否足够
    if( a[lson].sum >= e )return Query(lson, e);///左子树够的话去左子树
    if( a[lson].rsum +a[rson].lsum >= e )///判断中间是否足够
        return a[lson].R - a[lson].rsum + ;
    return Query(rson, e);///只能去右子树
} int main()
{
    int N, M, L, R, op;     while(scanf("%d%d", &N, &M) != EOF)
    {
        Build(, , N);         while(M--)
        {
            scanf("%d", &op);             if(op == )
            {
                scanf("%d", &R);                 if(R > a[].sum)///没有能放下的连续区间
                    printf("0\n");
                else
                {                     L = Query(, R);
                    R = L+R-;///求出来右端
                    printf("%d\n", L);
                    upDate(, L, R, );
                }
            }
            else
            {
                scanf("%d%d", &L, &R);
                upDate(, L, L+R-, );
            }
        }
    }     return ; } 

Hotel - poj 3667(求连续子区间)的更多相关文章

  1. Tunnel Warfare--- hdu1540 线段树求连续子区间

    题目链接 题意:有n个村庄,编号分别为1-n:由于战争会破坏村庄,但是我们也会修复: D x代表村庄x被破坏: Q x是求与x相连的有几个没有被破坏: R 是修复最后一次被破坏的村庄: 接下来有m个操 ...

  2. Hotel poj 3667

    Language: Default Hotel     Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18020   Acc ...

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

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  4. POJ 3667 Hotel(线段树)

    POJ 3667 Hotel 题目链接 题意:有n个房间,如今有两个操作 1.找到连续长度a的空房间.入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0 2.清空[a, a + b - 1 ...

  5. POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并

    看到讲课安排上 线段树有一节课"区间合并" 我是迷茫的 因为并没有见过 然后了解了一下题目 发现以前写过 还是很麻烦的树链剖分 大概是 解决带修改的区间查询"连续问题&q ...

  6. 求连续最大子序列积 - leetcode. 152 Maximum Product Subarray

    题目链接:Maximum Product Subarray solutions同步在github 题目很简单,给一个数组,求一个连续的子数组,使得数组元素之积最大.这是求连续最大子序列和的加强版,我们 ...

  7. Poj 3667

    这是第一题线段树的区间合并的题: 这类的题用于求连续的最长长度什么的: 这题我看的是一篇比较不错的博客: 我把我的理解注释在代码里了: #include <iostream>#includ ...

  8. 求连续数字的和------------------------------用while的算法思想

    前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...

  9. 求连续出现5次以上的值,并且取第5次所在id

    关键字:求连续出现5次以上的值,并且取第5次所在id 关键字:求在某列连续出现N次值的的数据,并且取第M次出现所在行 需求,求连续出现5次以上的值,并且取第5次所在id SQL SERVER: --测 ...

随机推荐

  1. POJ 1265 Area POJ 2954 Triangle Pick定理

    Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5227   Accepted: 2342 Description ...

  2. css.day05

    1. 外边距合并  不是bug  而是一个特性  (以最大的那个边距为准) 两个盒子是并列关系 两个盒子 父子级关系 1. border 2.overflow:hidden; 3. padding  ...

  3. (转) dedecms中自定义数据模型

    刚学习完dedecms的标签语法,我有很多困惑,觉得标签的意义比较抽象,不知道如何用标签来写一些具体的内容.如果有一些数据库的编程经验,就知道一个很常用的编程范例—增删改查.比如说,我要建立的是书本的 ...

  4. 【转】UITextView的使用详解

    //初始化并定义大小 UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(20, 10, 280, 30)]; te ...

  5. java_annotation_01

    一,Annotation简介 J2SE5.0提供了很多新的我,其中一个很重要的我就是对元数据的支持,在J2SE5.0中,这种元数据被称为注释,通过使用注释,程序开发人员可以在不改变原有逻辑的情况下,在 ...

  6. IE8’s Substr() Bug

    IE8不支持substr()函数, 第一个参数为负数,比如:var index = id.substr(-1, 1);替代:var index = id.substr(id.length-1, 1);

  7. Java学习----变量是什么

    1.变量必须拥有的类型 2.变量必须拥有的名字 变量:具备名字和类型的可以存放类型匹配的数据的量 public class Student { public static void main(Stri ...

  8. head First HTML与CSS读书笔记

    调整图片大小 有滚动条的图片可给不了好的用户体验,为了让图片的大小更适合浏览器窗口.这时候就需要对图片的大小进行调整看书之前.我调整图片大小的方式是在<img>元素使用 width 和 h ...

  9. [javascript]event属性

    1.clientX和clientY clientX和clientY是事件发生时,鼠标离浏览器可视文档区域左上角的位置 2.offsetX和offsetY offsetX和offsetY是事件发生时,鼠 ...

  10. 10个重要的Linux ps命令实战

    Linux作为Unix的衍生操作系统,Linux内建有查看当前进程的工具ps.这个工具能在命令行中使用. PS 命令是什么 查看它的man手册可以看到,ps命令能够给出当前系统中进程的快照.它能捕获系 ...