`
暴风雪
  • 浏览: 388758 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[线段树区间更新]poj 1823

 
阅读更多

题意

     一个旅馆有n个房间,有m次操作,每次操作可以是 1,从第a个房间开始的连续b个房间全部住满 2:从a开始的b个房间全部清空 3:查询n个房间中最长连续空房间的长度。

 

思路

     对于每个节点,记录这个节点的sta:状态,val:最长连续空房 lmx:区间内左侧连续空房间数 rmx:区间内右侧连续空房间数。并用子节点的值来更新父节点。

    更新节点时,记得用子节点的状态更新当前节点的sta值,否则父节点更新时会出错。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax = 1000000;
struct{
    int l,r,val,lmx,rmx,sta;   //0empty 1full -1mix
}node[3*nMax];

void gao(int u){
    if(node[u].sta == 0){
        node[u].val = node[u].lmx = node[u].rmx =  node[u].r - node[u].l + 1;
    }else{
        node[u].val = node[u].lmx = node[u].rmx =0;
    }
}
void build(int l ,int r ,int u){
    node[u].l = l;
    node[u].r = r;
    node[u].sta = 0;
    gao(u);
    if(l == r){
        return;
    }
    int m = (l+r)>>1;
    build(l ,m ,u*2);
    build(m+1 ,r ,u*2 + 1);
}
void update(int left ,int right ,int ope ,int u){
    int l = node[u].l;
    int r = node[u].r;
    if(l == left && r == right){
        node[u].sta = ope;
        gao(u);
        return;
    }
    if(node[u].sta == ope)return ;
    if(node[u].sta != -1){
        node[2*u].sta = node[2*u+1].sta = node[u].sta;
        gao(u*2),gao(u*2+1);
        node[u].sta = -1;
    }
    int m = (l + r)>>1;
    if(right <= m){
        update(left ,right ,ope ,u*2);
    }else{
        if(left >= m + 1){
            update(left ,right ,ope ,u*2+1);
        }else{
            update(left ,m ,ope ,u*2);
            update(m+1,right ,ope ,u*2+1);
        }
    }
    if(node[u*2].sta == 0){
        node[u].lmx = node[u*2].val + node[u*2+1].lmx;
    }else{
        node[u].lmx = node[u*2].lmx;
    }

    if(node[u*2+1].sta == 0){
        node[u].rmx = node[u*2+1].val + node[u*2].rmx;
    }else{
        node[u].rmx = node[u*2+1].rmx;
    }

    node[u].val = max(node[u*2].val,node[u*2+1].val);
    node[u].val = max(node[u].val,node[u*2].rmx+node[u*2+1].lmx);

    if(node[u*2].sta == node[u*2+1].sta){
        node[u].sta = node[u*2].sta;
    }
}
int main(){
    int n ,m ,ope ,a ,b ;
    while(scanf("%d%d",&n,&m)!=EOF){
        build(1 ,n ,1);
        while(m--){
            scanf("%d",&ope);
            if(ope == 1){
                scanf("%d%d",&a,&b);
                update(a ,a + b -1 ,1 ,1);
            }
            if(ope == 2){
                scanf("%d%d",&a,&b);
                update(a ,a + b -1 ,0 ,1);
            }
            if(ope == 3){
                printf("%d\n",node[1].val);
            }
        }
    }
    return 0;
}

 

0
0
分享到:
评论

相关推荐

    线段树入门学习(三)懒操作(兼解POJ1823) JAVA

    在本篇博文中,我们将深入探讨线段树的概念,以及如何实现懒惰更新(Lazy Propagation)策略,同时结合POJ1823问题进行实战应用。懒惰更新是优化线段树性能的关键技巧,它避免了频繁地对每个节点进行更新,从而减少...

    线段树练习POJ 3264

    线段树是一种数据结构,常用于处理区间查询与更新的问题,它能高效地支持动态维护区间最值、求和等问题。在本题“POJ 3264”中,我们可能面临的是一个区间最值或者区间求和的计算任务。线段树的基本思想是将数组或...

    线段树入门学习(二)(兼解POJ3468) JAVA

    POJ3468是一个典型的线段树应用题目,它要求对一组数进行多次区间加法操作,然后查询区间之和。线段树在这里可以高效地处理这些操作,避免了每次修改或查询时都遍历整个数组。 在Main.java中,我们可能会看到以下...

    POJ3277.rar_3277 poj_poj3277_多个面积_线段树

    2. 插入矩形:对于每个矩形,将其左边界和右边界映射到线段树的索引上,然后在对应区间内更新线段树的值,表示矩形的存在。更新方式可以是将该区间内的值加上矩形的宽度乘以高度。 3. 查询总面积:从线段树的根节点...

    poj2823.cpp.tar.gz_线段树

    线段树是一种数据结构,主要用于高效地处理区间(或段)上的查询与更新操作。在题目"poj2823"中,我们看到它被应用于寻找区域间的最大值和最小值。线段树通常用于解决动态规划问题,特别是在数组或序列上执行范围...

    POJ2528-Mayor's posters【区间映射压缩(离散化)+线段树】

    POJ2528-Mayor's posters 【区间映射压缩(离散化)+线段树】 解题报告+AC代码 http://hi.csdn.net/!s/83XZJU ========&gt; 我的所有POJ解题报告链接: http://blog.csdn.net/lyy289065406/article/details/6642573

    poj 2352 stars(树状数组,线段树)

    线段树也是一种高效的数据结构,它可以用来处理区间查询和更新操作。相比于树状数组,线段树更加灵活,可以支持更复杂的操作,但其实现也更为复杂。 - **初始化**:同样地,我们首先需要初始化一个足够大的数组来...

    线段树题目

    对于每个覆盖请求,更新线段树对应区间中的覆盖状态,并统计完全被覆盖的区间数量。这类问题的关键在于如何高效地更新和查询区间。 - **POJ 2528**:这是一道稍微复杂一点的线段覆盖问题,需要使用离散化技术。题目...

    ACM数据结构之树状数组和线段树

    4. **更新操作**:如果需要对区间内的元素进行更新,只需要更新覆盖该区间的线段树节点即可。 通过以上步骤,可以高效地解决 POJ3264 BalancedLineup 这类问题。 总结来说,线段树和树状数组都是强大的数据结构,...

    POJ 部分题解 解题报告

    6. **POJ 3468 线段树--long long VS int.txt**:线段树是处理区间查询和更新的有效数据结构。这个题目可能关注的是在处理大整数时,线段树的实现细节,尤其是`long long`类型与`int`类型的区别以及其在处理溢出问题...

    pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11

    线段树是一种高效的数据结构,用于处理区间查询和更新问题,比如在本例中,可能是对矩形区域的覆盖或者求解特定形状的面积。 线段树的基本概念是将一维数组划分为多个子区间,并将这些子区间对应到一棵二叉树的节点...

    二维树状数组学习之二:练习POJ 1195

    它在处理矩阵或网格状数据时非常有用,尤其对于需要频繁进行区间求和或者更新的场景。在本篇中,我们将深入学习二维树状数组的应用,并通过解决POJ 1195问题来实践这一概念。 POJ 1195题目要求我们计算一个二维矩阵...

    poj训练计划.doc

    - 线段树:如`poj2528, poj2828`。 - RMQ(区间查询):如`poj3264, poj3368`。 - 并查集的高级应用:如`poj1703, poj2492`。 - **搜索** - 最优化剪枝和可行性剪枝:如`poj3411, poj1724`。 - **动态规划** ...

    POJ3468.zip_ACM

    3. **实现操作**:编写函数来初始化线段树、更新节点值以及查询区间信息。更新操作可能涉及单点修改,而查询操作可能涉及求区间范围内的某种统计值。 4. **处理大整数**:由于提示中特别指出“注意long long int”...

    二维树状数组练习 POJ 2029

    它扩展了一维树状数组(也称作线段树),能够处理二维或多维的数组更新和查询操作。在POJ 2029这个题目中,我们可能面临的问题是需要对一个二维矩阵进行动态更新和求和查询,例如计算某一个矩形区域内的元素总和。 ...

    poj1990.rar_POJ 19_poj_poj19

    首先,我们要理解树状数组(也称作线段树)这一数据结构。树状数组是一种用于高效处理区间查询和修改的结构,其基础是每个节点存储一个区间内的累积信息。对于POJ 1990题目,我们需要解决的问题可能涉及到对某一区间...

    acm训练计划(poj的题)

    - (poj2488, poj3083, poj3009, poj1321, poj2251):区间树、线段树等数据结构,用于处理区间查询问题。 6. **字典树(Trie)**: - (poj2513):一种高效的字符串检索数据结构。 ### 四、状态压缩 1. **状态...

    acm新手刷题攻略之poj

    - 区间查询问题通常涉及线段树或树状数组等数据结构。 5. **字符串匹配** - 推荐题目:[poj1961](https://vjudge.net/problem/POJ-1961)、[poj2406](https://vjudge.net/problem/POJ-2406) - 字符串匹配算法如...

    图的深搜+树状数组练习 POJ 3321(JAVA)

    树状数组,又称线段树,是一种高效的数据结构,主要用于处理动态区间查询和更新问题。它能够在O(logn)的时间复杂度内完成对一个区间的修改和查询操作。树状数组通常用于解决求和、计数或找到某个范围内的最大值、...

Global site tag (gtag.js) - Google Analytics