UVALive 4108 - SKYLINE(线段树区间更新)

题目链接 https://cn.vjudge.net/problem/UVALive-4108

【题意】
在地平线上依次建造n座建筑物,建筑物的修建按照从后往前的顺序,新建筑物可能会挡住一些老建筑物。在修建完一座建筑物后,统计它在多长的部分是最高的(可以和其他建筑物并列最高),把这个长度称为该建筑的“覆盖度”

【输入格式】
多组输入,第一行为数据组数。每组数据第一行为建筑物个数n(1<=n<=1e5)以下n行按照先后顺序给出n座建筑物的的左右边界和高度l,r,h(0 < l < r < 1e5,0 < h<=1e9)

【输出格式】
对每组数据,输出所有建筑物的总覆盖度

【思路】
对整个区间建立一个线段树,维护最大值和最小值,在每次更新的时候,如果当前区间的最小值比建筑物的高度还大,那么就不用更新区间的值了,如果当前区间的最大值小于等于建筑物高度,那么答案就要加上这一段区间的长度,并把这段区间更新成建筑物的高度

#include<bits/stdc++.h>
#define node tree[id]
#define lson tree[id<<1]
#define rson tree[id<<1|1]
using namespace std;

const int maxn=100050;

int n;
struct Tree{
    int left,right;
    int maxv,minv,lazy;
}tree[maxn<<2];

void pushup(int id){
    node.maxv=max(lson.maxv,rson.maxv);
    node.minv=min(lson.minv,rson.minv);
}

void pushdown(int id){
    if(node.lazy && node.left!=node.right){
        lson.lazy=node.lazy;
        lson.maxv=lson.minv=node.lazy;
        rson.lazy=node.lazy;
        rson.maxv=rson.minv=node.lazy;
        node.lazy=0;
    }
}

void build(int id,int le,int ri){
    node.left=le;
    node.right=ri;
    node.lazy=0;
    node.maxv=node.minv=0;
    if(le==ri) return;
    int mid=(le+ri)>>1;
    build(id<<1,le,mid);
    build(id<<1|1,mid+1,ri);
}

int update(int id,int le,int ri,int val){
    if(node.left==le && node.right==ri && node.minv>val) return 0;
    if(node.left==le && node.right==ri && node.maxv<=val){
        if(node.maxv<val){
            node.lazy=val;
            node.maxv=node.minv=val;
        }
        return ri-le+1;
    }
    pushdown(id);
    int ans=0;
    int mid=(node.left+node.right)>>1;
    if(ri<=mid) ans=update(id<<1,le,ri,val);
    else if(le>mid) ans=update(id<<1|1,le,ri,val);
    else ans=update(id<<1,le,mid,val)+update(id<<1|1,mid+1,ri,val);
    pushup(id);
    return ans;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int ans=0;
        build(1,1,100000);
        scanf("%d",&n);
        for(int i=0;i<n;++i){
            int x,y,h;
            scanf("%d%d%d",&x,&y,&h);
            ans+=update(1,x,y-1,h);
        }
        printf("%d\n",ans);
    }
    scanf("%d",&T);
    return 0;
}
posted @ 2018-08-11 10:55  不想吃WA的咸鱼  阅读(157)  评论(0编辑  收藏  举报