【UVA】1232 - SKYLINE(线段树减枝)

注意中间的减枝,还需要用一个tr[i]记录结点的值,用col[i]记录结点区间是否被全覆盖。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 111111;
const int maxd = 100001;
#define lson pos<<1
#define rson pos<<1|1
int col[maxn << 2];
int  tr[maxn << 2];
int ret;
void pushdown(int pos){
    if(col[pos] != -1){
        tr[lson] = col[pos]; tr[rson] = col[pos];
        col[lson]= col[pos]; col[rson]= col[pos];
        col[pos] = -1;
    }
    return;
}
void Query(int L,int R,int l,int r,int pos,int value){
    if(col[pos] != -1 && tr[pos] > value) return;  //这个减枝非常重要,如果不加就TLE了
    if(col[pos] != -1){         //这个区间是一个统一区间
        if(L <= l && r <= R){
             if(value >= tr[pos]){
                ret += (r - l + 1);
                tr[pos] = value;  //区间赋值
                col[pos]= value;  //懒惰标记
             }
            return;
        }
    }
    pushdown(pos);
    int m = (l + r) >> 1;
    if(L <= m)
        Query(L,R,l,m,lson,value);
    if(R  > m)
        Query(L,R,m + 1,r,rson,value);
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n = 0,m;
        ret = 0;
        scanf("%d",&m);
        memset(col,0,sizeof(col));
        memset(tr,0,sizeof(tr));
        for(int i = 0; i < m; i++){
            int L,R,v;
            scanf("%d%d%d",&L,&R,&v);
            Query(L,R - 1,1,maxd,1,v);
        }
        printf("%d\n",ret);
    }
    return 0;
}
时间: 2024-10-26 12:53:28

【UVA】1232 - SKYLINE(线段树减枝)的相关文章

UVA 1232 - SKYLINE(线段树)

UVA 1232 - SKYLINE 题目链接 题意:按顺序建房,在一条线段上,每个房子一个高度,要求出每间房子建上去后的轮廓线 思路:线段树延迟更新,一个setv作为高度的懒标记,此外还要在开一个cover表示当前结点一下是否都为同一高度 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson(x) ((x<<1)+1)

Uva 1232 - SKYLINE ( 线段树 + 区间更新 )

Uva 1232 SKYLINE (线段树 + 区间更新) 题意: 按照顺序在地面上建造放在,每个房子的高度为h,操作 l r h 表示 在(l,r] 区间建立一个高度为h的房子.统计每次建立完房子之后的overlap值之和 overlap值表示[ 修完一座房子之后,统计它在多长的部分是最高的(可以和其他房子并列高) ]如样例图,按照灰.黒.白的顺序建立房子 ans = (11-5) + (5-1) + (5-3) + (13-11) = 6 + 4 + 4 = 14 分析: 一开始一直想不明白

UVA 1455 - Kingdom(线段树+并查集)

UVA 1455 - Kingdom 题目链接 题意:给定一些城市坐标点,连在一起的城市称为一个州,现在用两种操作,road表示把城市a,b建一条路,line表示询问一个y轴上穿过多少个州,和这些州共包含多少个城市 思路:利用并查集维护每个州的上界和下界还有城市个数,然后每次加进一条路的时候,根据两个集合的位置可以处理出区间的州和城市数如何进行加减,然后利用线段树搞就可以了 代码: #include <cstdio> #include <cstring> #include <

uva 11525 - Permutation(线段树)

题目链接:uva 11525 - Permutation 题目大意:给定n和k,n给定的方式为k个si,根据公式计算出n,求一个由1~k组成的长度为k的序列的第n个排序 解题思路:根据公式的性质,等于对于每个位置找当前状态下第si小的数.线段树子节点均为1,维护和,查询时传入参数查找即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int ma

UVA1232 - SKYLINE(线段树区间修改)

题目链接 题目大意:按照顺序盖楼,如果这个位置(当前要盖的楼覆盖范围内)要新建的楼的高度>=之前就有的最大高度,那么就+1.最后输出这个+1的总数. 解题思路:线段树区间修改值,并且每次修改的时候返回修改的位置总数.因为可能左右子树的高度会有不同,所以这里加入一个sign来表示左右这一段是否高度一致. 代码: #include <cstdio> #include <cstring> const int maxn = 1e5 + 5; #define lson(x) ((x)&

UVALive - 4108 SKYLINE[线段树]

UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug Description The skyline of Singapore as viewed from the Marina Promenade (shown on the left) is one of the iconic scenes of Singapore. Country X would als

uva 1400 - &quot;Ray, Pass me the dishes!&quot;(线段树)

题目链接:uva 1400 - "Ray, Pass me the dishes!" 题目大意:给定一个长度为n个整数序列,对m次询问作出回答,对于每次询问(a,b),找到两个下标x,y使得x到y的连续和为区间a,b中最大的连续和,如果存在多解优先x小,然后y小. 解题思路:线段树,对于每个节点维护三个线段值: max_sub:区间连续最大和 max_prefix:区间连续前缀最大和 max_suffix:区间连续后缀最大和 建树的过程维护三个值,查询时只需考虑左右子节点的max_su

uva 11992 线段树对矩阵进行更新查询

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143 把矩阵变成一行,然后计算位置,lrj给了线段树数组做法 但是我做的线段树空间过大,直接爆掉,所以换方法了 主要还是测试自己的线段树区间更新的模板 各种RE+WA之后AC,,,,, 做的时候出现的几个错误: 1.行和列弄错 2.build初始化的时候,mmin mmax 都初始化为0才对

uva 12436 - Rip Van Winkle&#39;s Code(线段树)

题目链接:uva 12436 - Rip Van Winkle's Code 题目大意:四种操作,操作见题目. 解题思路:即用线段树维护一个等差数列,因为一个等差加上一个等差还是一个等差数列,所以对于每个节点记录区 间左端的值,也就是首项,以及公差即可.因为还有一个S操作,所以要开一个标记记录区间值是否相同. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; ty