UVALive - 4108 SKYLINE(线段树区间覆盖+剪枝)

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

思路:线段树维护区间最大值,最小值,新加入的墙的高度如果小于区间最小值,不做处理,比最大值大,覆盖掉之前的最大值最小值,添加lazy标记,因为维护的是坐标轴上的点,建树的停止条件l+1==r

#include 
#define lson num << 1
#define rson num << 1 | 1
#define MAXN 100005
using namespace std;
struct node
{
    int l,r;
    int Max,Min;
    int lazy;
}tree[MAXN << 2];
int ans;
void build(int num,int l,int r)
{
    tree[num].l = l;
    tree[num].r = r;
    tree[num].Max = tree[num].Min = 0;
    tree[num].lazy = 0;
    if(l + 1 == r) return;
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid,r);
}
void pushdown(int num)
{
    if(tree[num].lazy) {
        tree[lson].Max = tree[lson].Min = tree[lson].lazy = tree[num].lazy;
        tree[rson].Max = tree[rson].Min = tree[rson].lazy = tree[num].lazy;
        tree[num].lazy = 0;
    }
}
void pushup(int num)
{
    tree[num].Max = max(tree[lson].Max,tree[rson].Max);
    tree[num].Min = min(tree[lson].Min,tree[rson].Min);
}
void getans(int num,int l,int r,int h)
{
    if(h < tree[num].Min) return;
    if(tree[num].l == l && tree[num].r == r && tree[num].Max <= h) {
        tree[num].Max = tree[num].Min = tree[num].lazy = h;
        ans += (r - l);
        return;
    }
    pushdown(num);
    int mid = (tree[num].l + tree[num].r) >> 1;
    if(r <= mid) getans(lson,l,r,h);
    else if(l >= mid) getans(rson,l,r,h);
    else {
        getans(lson,l,mid,h);
        getans(rson,mid,r,h);
    }
    pushup(num);
}
int main(void)
{
    int n,l,r,h;
    int T;
    scanf("%d",&T);
    while(T--) {
        ans = 0;
        scanf("%d",&n);
        build(1,1,MAXN);
        while(n--) {
            scanf("%d %d %d",&l,&r,&h);
            getans(1,l,r,h);
        }
        printf("%d\n",ans);
    }
    scanf("%d",&T);
    return 0;
}

 

你可能感兴趣的:(ACM-数据结构)