题意:
给定n个线段以及没个线段上的高度,求最终所有线段的矩形面积并。
分析:
由于数据范围较大,所以采用离散化,再用每个点进行建树,之前没这么建过线段树,学到了。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=4e4+10;
ll x[maxn],y[maxn],id[maxn<<1],tree[maxn*8],h[maxn];
void change(int tl,int tr,int i,int l,int r,ll v){
if(tl>=r||tr<=l) return;
if(tl<=l&&r<=tr){
tree[i]=max(tree[i],v);
return;
}
if(tree[i]>=v) return;
int mid=l+r>>1;
change(tl,tr,i<<1,l,mid,v);
change(tl,tr,i<<1|1,mid,r,v);
}
ll query(int i,int l,int r,ll h){
if(h>tree[i]) tree[i]=h;
if(l+1==r) return (id[r]-id[l])*tree[i];
int mid=l+r>>1;
return query(i<<1,l,mid,tree[i])+query(i<<1|1,mid,r,tree[i]);
}
int main(){
int n;
int cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld",&x[i],&y[i],&h[i]);
id[++cnt]=x[i];
id[++cnt]=y[i];
}
sort(id+1,id+1+cnt);
cnt=unique(id+1,id+1+cnt)-(id+1);
memset(tree,0,sizeof tree);
for(int i=1;i<=n;i++){
int tx=lower_bound(id+1,id+1+cnt,x[i])-id;
int ty=lower_bound(id+1,id+1+cnt,y[i])-id;
change(tx,ty,1,1,cnt,h[i]);
}
printf("%lld\n",query(1,1,cnt,0));
return 0;
}