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

[线段树区间合并]poj 3667

 
阅读更多

i题意

       和poj1823差不多,加了一个查询最左可行的位置

思路

       查询的时候根据不同的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 query(int val ,int u){
    if(node[u].sta == 0 && node[u].val >= val){
        return node[u].l;
    }
    if(node[u].sta == 1){
        return 0;
    }
    if(node[u].sta == -1){
        if(node[u*2].val >= val){
            return query(val ,2*u);
        }else{
            if(node[2*u].rmx + node[2*u+1].lmx >= val){
                return node[2*u].r - node[2*u].rmx + 1;
            }else{
                return query(val ,u*2 + 1);
            }
        }
    }
    return 0;
}

int main(){
    int n ,m ,a ,b ,c;
    while(scanf("%d%d",&n,&m)!=EOF){
        build(1 ,n ,1);
        while(m--){
            scanf("%d",&a);
            if(a == 1){
                scanf("%d",&b);
                c = query(b ,1);
                printf("%d\n",c);
                if(c != 0){
                    update(c ,c+b-1 ,1 ,1);
                }
            }else{
                scanf("%d%d",&b,&c);
                update(b ,b + c -1 ,0 ,1 );
            }
        }
    }
    return 0;
}

 

0
1
分享到:
评论

相关推荐

    线段树练习POJ 3264

    线段树的基本思想是将数组或序列分成多个部分(通常是二分),每个部分对应线段树的一个节点,通过节点间的合并操作,快速获取区间信息。 线段树的构建通常分为两个阶段:初始化和构造。初始化时,我们将原始数组中...

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

    标题中的“POJ3277.rar_3277 poj_poj3277_多个面积_线段树”是指一个与编程竞赛相关的压缩文件,特别提到了POJ(Problemset Online Judge)的第3277号问题。POJ是一个著名的在线编程竞赛平台,参与者需要解决各种...

    poj2823.cpp.tar.gz_线段树

    在"poj2823"这个问题中,我们可能需要维护两个线段树,分别记录数组的最大值和最小值,以便于在查询时快速找到区间内的最大最小值。线段树的结构允许我们在O(log n)的时间复杂度内完成一次查询或更新,这对于大数据...

    pku1151.rar_Atlantis_pku 11_poj Atlant_poj Atlantis_poj11

    线段树的基本概念是将一维数组划分为多个子区间,并将这些子区间对应到一棵二叉树的节点。每个节点代表一个区间,叶节点对应原始数组的元素,非叶节点则表示其子节点对应的区间的合并值。通过这样的结构,可以快速地...

    poj训练计划.doc

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

    acm新手刷题攻略之poj

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

    2010FZUACM_高级数据结构习题讲解1

    以上就是高级数据结构习题讲解中的核心知识点,包括树状数组、二维和三维树状数组的使用,线段树在处理区间问题上的应用,动态规划和并查集在特定问题中的策略。理解并掌握这些工具和方法,有助于解决复杂的算法竞赛...

    poj推荐50题

    线段树是一种高效的数据结构,可以用来解决区间查询等问题。 #### 题目示例及解析: - **2352** 和 **2528** 两题适合了解线段树的基本应用,虽然没有最少题数要求,但练习线段树对于提高算法能力非常有帮助。 ###...

    NOIP NOI 信息学竞赛 ACM-ICPC POJ(北京大学在线评测系统)刷题推荐 OI复习计划 算法大纲

    线段树用于区间查询和更新,如2352、2528等。 12. **计算几何**(Computational Geometry) 包括点、线、面的几何运算,如1113、1292、2148等,1113是凸包算法的基础题。 13. **高精度**(Arbitrary Precision ...

    ACM算法总结--最新总结的ACM算法

    1. **高级数据结构**(如poj2528, poj2828, poj2777, poj2886, poj2750):包括线段树、树状数组、Trie树等,用于解决复杂的数据查询和更新问题。 2. **平衡树**(如poj2482, poj2352):如AVL树、红黑树等,保持树...

    算法训练方案详解

    - **示例题目**: POJ 3267, POJ 1836, POJ 1260, POJ 2533, POJ 3176, POJ 1080, POJ 1159 - **注意事项**: 理解每种模型的状态定义和转移方程。 #### 六、数学 **1. 组合数学** - **定义**: 研究组合结构的...

    ACM中的RMQ和LCA问题

    总的来说,RMQ和LCA是ACM中重要且实用的数据结构问题,它们涉及到动态规划、线段树、Sparse Table、并查集等多种数据结构和算法,对于提高解决问题的能力和效率具有很高的价值。学习和掌握这些知识对于参赛者来说至...

    算法学习攻略

    11. **线段树**:线段树是一种高级的数据结构,用于区间查询和修改,推荐2352和2528。 12. **计算几何**:处理几何问题,例如1113(凸包算法)和1292、2148、2653、1584。 13. **高精度计算**:处理大整数运算,如...

    cPP.zip_二部图

    线段树是一种数据结构,可以支持区间查询和更新操作,其时间复杂度为O(logn)。而树状数组,又称斐波那契堆,同样可以高效地处理区间查询和单点修改问题,它的核心思想是维护一个数组,并通过前缀和快速计算区间和。 ...

    ACM北大训练

    - **定义**: 线段树是一种用于区间查询和更新操作的数据结构。 - **应用场景**: 在区间查询问题、动态规划等问题中有广泛应用。 - **示例题目**: - poj2528: 涉及线段树的应用。 ##### 2. 静态二叉检索树 - **定义...

    RMQ与LCA ACM必备

    线段树(Segment Tree)也是一种解决RMQ问题的有效工具,可以实现O(logn)的查询和更新操作。此外,还可以通过滚动数组(Sliding Window)优化特定情况下的空间占用,如POJ 2823问题。 **LCA(Least Common ...

    常用算法 (2).pdf

    5. **线段树**:用于动态查询和更新区间数据。 6. **并查集**:维护集合的连接关系,支持合并和查询操作。 7. **动态规划**:LCS(最长公共子序列)、最长递增子串、三角剖分、记忆化DP等。 8. **博弈类算法**:博弈...

    挑战程序设计竞赛(第2版)

    3.3.1 线段树 3.3.2 Binary Indexed Tree 3.3.3 分桶法和平方分割 3.4 熟练掌握动态规划 3.4.1 状态压缩DP 3.4.2 矩阵的幂 3.4.3 利用数据结构高效求解 3.5 借助水流解决问题的网络流 3.5.1 最大流 3.5.2 最小割 ...

    常用算法.docx

    3. **线段树**:一种数据结构,用于高效地处理区间查询和修改操作。 4. **并查集**:用于处理集合的合并与查询是否属于同一集合的问题,路径压缩可以优化其性能。 5. **判断点在多边形内**:在计算几何中,判断一...

Global site tag (gtag.js) - Google Analytics