题意:
我们要在地平线(看成数轴)上依次建造n座建筑物。建筑物的修建按照从后往前的顺序,因此新建筑物可能会挡住一部分老建筑物。
修建完一座建筑物后,统计它在多长的部分最长(可以和其他建筑物并列最高),并把这个长度称为“覆盖度”。
求所有建筑物的总覆盖度
分析:
维护一个区间的最大值还有最小值,如果在当前的区间的最小值还是大于当前的所要盖的楼房的高度的时候就放弃,直接return
如果是大于或者等于的话就更新区间的lazy,如果是介于两者之间的话,那就继续往下面找,直到找到区间的最底层然后返回
这里有几个地方需要注意,就是区间问题的传参
#include<bits/stdc++.h>
using namespace std;
#define lson id<<1
#define rson id<<1|1
const int N = 1e5+10;
struct node{
int l,r,maxv,minv,lazy;
}a[N<<2];
int ans;
void pushup(int id){
a[id].maxv=max(a[lson].maxv,a[rson].maxv);
a[id].minv=min(a[lson].minv,a[rson].minv);
}
void pushdown(int id){
if(a[id].lazy!=0){
a[lson].lazy=a[rson].lazy=a[id].lazy;
a[rson].minv=a[lson].minv=a[id].lazy;
a[lson].maxv=a[rson].maxv=a[id].lazy;
a[id].lazy=0;
}
}
void build(int id,int l,int r){
a[id].l=l;
a[id].r=r;
a[id].lazy=a[id].maxv=a[id].minv=0;
if(l==r){
return ;
}
int mid=(a[id].l+a[id].r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
}
void update(int id,int l,int r,int val){
if(a[id].minv>val)
return ;
if(a[id].l==l&&a[id].r==r){
if(a[id].maxv<=val){
a[id].maxv=val;
a[id].minv=val;
a[id].lazy=val;
ans+=r-l+1;
return ;
}
if(l==r) return ;
}
pushdown(id);
int mid=(a[id].l+a[id].r)/2;
if(r<=mid) update(lson,l,r,val);
else if(l>mid) update(rson,l,r,val);
else{
update(lson,l,mid,val);
update(rson,mid+1,r,val);
}
pushup(id);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int t,n;
while(scanf("%d",&t)!=EOF,t){
while(t--){
scanf("%d",&n);
build(1,1,100019);
ans=0;
int pre=0;
for(int i=0;i<n;i++){int l,r,val;
scanf("%d%d%d",&l,&r,&val);
update(1,l,r-1,val);
//解释一下这里:如果是两组数据分别为4--8、8--10;如果是直接去调用
//那么8这一个点就会被改变,如果第一个是高的,也就是说矮的点将其覆盖了
//所以这个临界点是不能被取到的,那么这也就是为什么update函数里面ans+=r-l+1的原因了
}
printf("%d\n",ans);
}
}
return 0;
}