由于要求最小差值
考虑枚举每个序号 i n d e x index index作为最小值来求
首先 i n d e x index index的值越小越好,所以我们把所有覆盖 i n d e x index index的区间加进去
但是这样有些位置的数字也减小了啊!!但其实差值是不变的,所以一定是更优的
于是我们可以把所有区间按照左端点排序
只要左端点比 i n d e x index index小就说明覆盖了 i n d e x index index(因为 i n d e x index index从 1 1 1起)
我们就加进来放在线段树上,然后查询区间最大值
然后之前加入的那些区间,我们在右端点处打个标记,说明它的作用到右端点位置
到了这个点,我们就消除那个区间的影响就好了
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mid (l+r>>1)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
const int maxn = 2e5+10;
int n,m,ans;
struct p
{
int l,r,w;
bool operator < (const p&tmp ) const
{
if( l==tmp.l ) return r<tmp.r;
return l<tmp.l;
}
}a[maxn];
vector<p>vec[maxn];
int w[maxn<<2],laz[maxn<<2],h[maxn];
void pushdown(int rt,int l,int r)
{
if( laz[rt]==0 ) return;
laz[ls] += laz[rt],laz[rs] +=laz[rt];
w[ls] +=laz[rt], w[rs] += laz[rt];
laz[rt] = 0;
}
void build(int rt,int l,int r)
{
if( l==r ) { w[rt] = h[l]; return; }
build(lson); build(rson);
w[rt] = max( w[ls],w[rs] );
}
void add(int rt,int l,int r,int L,int R,int val)
{
if( l>=L&&r<=R ) { laz[rt]+=val; w[rt]+=val; return; }
if( l>R||r<L ) return;
pushdown(rt,l,r);
add(lson,L,R,val); add(rson,L,R,val);
w[rt] = max( w[ls],w[rs] );
}
int ask(int rt,int l,int r,int index)
{
if( l>index||r<index ) return 0;
if( l==r&&l==index ) return w[rt];
pushdown(rt,l,r);
return ask(lson,index)+ask(rson,index);
}
signed main()
{
cin >> n >> m;
for(int i=1;i<=n;i++) cin >> h[i];
build(1,1,n);
for(int i=1;i<=m;i++)
cin >> a[i].l >> a[i].r >> a[i].w;
sort( a+1,a+1+m );
int last = 1,ans = 0;
for(int i=1;i<=n;i++)
{
while( a[last].l<=i&&last<=m )
{
add( 1,1,n,a[last].l,a[last].r,-a[last].w );
vec[a[last].r].push_back( a[last] );
last++;
}
ans = max( ans,w[1]-ask(1,1,n,i) );
for(int j=0;j<vec[i].size();j++)
add(1,1,n,vec[i][j].l,vec[i][j].r,vec[i][j].w);
}
cout << ans;
}