又是一个简单的扫描线入门题
因为这题的题面的特殊性,连线段树都不需要了
用来代替线段树的是一个支持
插入一个数,删除一个数,求当前集合中最大的数
的一个集合
幸运的是std::multiset就支持以上操作
so,详细见代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
#define LL long long
multiset<LL> S;
LL big(){
set<LL>::iterator it = S.end();
it--;
return *it;
}
const int maxn = 81234;
struct event{
LL h;
LL t;
int add;
void init(LL H,LL tim,int a){
add = a;
h = H;
t = tim;
}
};
event eve[maxn];
bool cmp(event a,event b){
return a.t < b.t;
}
int main(){
int n;
while(~scanf("%d",&n)){
LL l,r,h;
int len = 0;
while(n--){
scanf("%lld %lld %lld",&l,&r,&h);
eve[len++].init(h,l,1);
eve[len++].init(h,r,-1);
}
sort(eve,eve+len,cmp);
LL ans = 0;
S.clear();
S.insert(0);
for(int i=0;i<len;i++){
if(i > 0 && eve[i].t != eve[i-1].t){
ans += big() * (eve[i].t - eve[i-1].t);
}
if(eve[i].add==1){
S.insert(eve[i].h);
}
else{
S.erase(S.find(eve[i].h));
}
}
printf("%lld\n",ans);
}
return 0;
}