传送门biu~
在线段树上打修改标记,如果两个标记在同一条线段上显然保留最大的那个标记。最后dfs一遍求和。在dfs时,如果线段树上的某一条线段没被创建过,那么一定不会有这条线段的子线段被打过标记。此时返回这条线段被标记过的最大值乘这条线段的长度。
#include<bits/stdc++.h>
using namespace std;
int n;
long long ans;
struct Node{
Node *ch[2];
int x;
Node(){ch[0]=ch[1]=NULL;x=0;}
}*root;
void modify(Node *&o,int L,int R,int l,int r,int w){
if(!o) o=new Node;
if(L==l && R==r){o->x=max(o->x,w);return;}
int mid=L+R>>1;
if(r<=mid) modify(o->ch[0],L,mid,l,r,w);
else if(l>mid) modify(o->ch[1],mid+1,R,l,r,w);
else modify(o->ch[0],L,mid,l,mid,w),modify(o->ch[1],mid+1,R,mid+1,r,w);
}
void dfs(Node *o,int L,int R,int w){
if(!o){ans+=1ll*(R-L+1)*w;return;}
int mid=L+R>>1;
dfs(o->ch[0],L,mid,max(w,o->x));
dfs(o->ch[1],mid+1,R,max(w,o->x));
}
int main(){
scanf("%d",&n);
while(n--){
int l,r,w;
scanf("%d%d%d",&l,&r,&w);--r;
if(l>r) continue;
modify(root,1,1e9,l,r,w);
}
dfs(root,1,1e9,0);
printf("%lld\n",ans);
return 0;
}