#define HAVE_STRUCT_TIMESPEC
#include
using namespace std;
int x[1000007],y[1000007];
long long a[1000007];
int cc[2000007];
vector
long long mx[4000007],lz[4000007],mxid[4000007];
long long cmx,cid;
int n,cnt;
void up(int rt){
if(mx[rt<<1]>=mx[rt<<1|1]){
mx[rt]=mx[rt<<1];
mxid[rt]=mxid[rt<<1];
}
else{
mx[rt]=mx[rt<<1|1];
mxid[rt]=mxid[rt<<1|1];
}
}
void down(int rt){
lz[rt<<1]+=lz[rt];
lz[rt<<1|1]+=lz[rt];
mx[rt<<1]+=lz[rt];
mx[rt<<1|1]+=lz[rt];
lz[rt]=0;
}
void build(int rt,int l,int r){
if(l==r){
mx[rt]=-cc[l];
mxid[rt]=l;
return ;
}
build(rt<<1,l,(l+r)>>1);
build(rt<<1|1,((l+r)>>1)+1,r);
up(rt);
}
void update(int rt,int l,int r,int L,int R,long long k){
if(L<=l&&r<=R){
lz[rt]+=k;
mx[rt]+=k;
return ;
}
down(rt);
if(L<=((l+r)>>1))
update(rt<<1,l,(l+r)>>1,L,R,k);
if(R>((l+r)>>1))
update(rt<<1|1,((l+r)>>1)+1,r,L,R,k);
up(rt);
}
void query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
if(mx[rt]>cmx){
cmx=mx[rt];
cid=mxid[rt];
}
return ;
}
down(rt);
if(L<=((l+r)>>1))
query(rt<<1,l,(l+r)>>1,L,R);
if(R>((l+r)>>1))
query(rt<<1|1,((l+r)>>1)+1,r,L,R);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cnt=0;
cin>>n;
for(int i=1;i<=n;++i){
cin>>x[i]>>y[i]>>a[i];
cc[++cnt]=x[i];
cc[++cnt]=y[i];
}
sort(cc+1,cc+1+cnt);
cnt=unique(cc+1,cc+1+cnt)-(cc+1);//离散化,二维平面压缩到y=x直线上
for(int i=1;i<=n;++i){
x[i]=lower_bound(cc+1,cc+1+cnt,x[i])-cc;
y[i]=lower_bound(cc+1,cc+1+cnt,y[i])-cc;
if(x[i]>y[i])
swap(x[i],y[i]);
v[x[i]].push_back({y[i],a[i]});//储存坐标
}
long long ans=0;
int cx=cc[cnt]+1;
int cy=cx;
build(1,1,cnt);
for(int i=cnt;i;--i){//从大到小枚举左端点
for(int j=0;j
int r=v[i][j].first;
long long w=v[i][j].second;
update(1,1,cnt,r,cnt,w);//当前区间更新右端点为[r,inf)的答案,用线段树实现区间加法,维护区间最大值以及最大值的下标
}
cmx=-2e18;
cid=-1;
query(1,1,cnt,i,cnt);//查询区间(最大值-R+L),L为当前左端点,R为右端点,建树时直接对贡献-R
if(ans
ans=cmx+cc[i];
cx=cc[i];
cy=cc[cid];
}
}
cout<
cout<
return 0;
}