题目链接:https://vjudge.net/problem/UVALive-4108
思路:线段树维护区间最大值,最小值,新加入的墙的高度如果小于区间最小值,不做处理,比最大值大,覆盖掉之前的最大值最小值,添加lazy标记,因为维护的是坐标轴上的点,建树的停止条件l+1==r
#include <bits/stdc++.h>
#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;
}