这题写了三四天,真是写郁闷了,后来才发现自己这题写2B了,唉,桑心。
题意:在地平线上依次建n座建筑物。建筑物的修建按照从后往前的顺序,修建完一座建筑物以后,统计它在多长的部分是最高的,并把这个长度称为“覆盖度”,最后输出总的覆盖度。
思路:刚开始的时候,我的思路比较简单,就是记录每个区间最高的建筑物有多高,如果要修建的这个建筑物的高度比这个区间最高的建筑物还高,那么这个结果就要加上这个区间的长度,否则就接着找下去。但是这样的话会有问题,将一个区间分为两部分的时候,分开的那部分很难计算,比如区间[1,6]分为两个区间[1,3]、[4,6],那么[3,4]这个区间的值就不好计算了,当时写的时候加了好多特判,搞得乱七八糟的,还是各种wrong。其实这个问题换个角度看会容易很多:对于每个单位区间,比如[3,3],我们记录的值可以看做从3到4之前的这个区间中建筑物的最大值,这样的话,每次更新的时候更新的就是l~r-1的这段区间,查询按上面的方法去搞就行了,当这个区间最高的建筑物比要修建的建筑物低,那么直接在sum中加上区间的长度r-l+1即可。
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
//typedef long long ll;
const int maxn=100000+10;
const int N=100000;
int hightv[maxn<<2],setv[maxn<<2];
bool flag[maxn<<2];
int sum;
void PushUp(int rt)
{
int ls=rt<<1,rs=rt<<1|1;
hightv[rt]=max(hightv[ls],hightv[rs]);
flag[rt]=(hightv[ls]==hightv[rs])&&flag[ls]&&flag[rs];
}
void PushDown(int rt)
{
if(setv[rt]>=0)
{
int ls=rt<<1,rs=rt<<1|1;
if(setv[rt]>=hightv[ls])
{
hightv[ls]=setv[rt];
flag[ls]=true;
}
if(setv[rt]>=hightv[rs])
{
hightv[rs]=setv[rt];
flag[rs]=true;
}
setv[ls]=max(setv[ls],setv[rt]);
setv[rs]=max(setv[rs],setv[rt]);
setv[rt]=-1;
}
}
void build(int l,int r,int rt)
{
hightv[rt]=0;
setv[rt]=-1;
flag[rt]=true;
if(l==r) return;
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
void Update(int v,int L,int R,int l,int r,int rt)
{
if(l>=L&&r<=R&&hightv[rt]<=v)
{
sum+=(r-l+1);
setv[rt]=hightv[rt]=v;
flag[rt]=true;
return;
}
if(l>=L&&r<=R&&hightv[rt]>v&&flag[rt])
{
return;
}
PushDown(rt);
int m=(l+r)>>1;
int ls=rt<<1,rs=rt<<1|1;
if(m>=L)
Update(v,L,R,l,m,ls);
if(m<R)
Update(v,L,R,m+1,r,rs);
PushUp(rt);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,l,r,h;
int t;
while(cin>>t)
{
if(t==0) break;
while(t--)
{
cin>>n;
build(1,N,1);
int res=0;
for(int i=0;i<n;++i)
{
cin>>l>>r>>h;
sum=0;
Update(h,l,r-1,1,N,1);
res+=sum;
}
cout<<res<<endl;
}
}
return 0;
}