1035 小翔和泰拉瑞亚 线段树 区间修改使最小值最大值差距最大 思维

链接:https://ac.nowcoder.com/acm/contest/26896/1035
来源:牛客网

题目描述

小翔爱玩泰拉瑞亚 。
一天,他碰到了一幅地图。这幅地图可以分为n列,第i列的高度为Hi,他认为这个地图不好看,决定对它进行改造。
小翔又学会了m个魔法,实施第i个魔法可以使地图的第Li列到第Ri列每一列的高度减少Wi,每个魔法只能实施一次,魔法的区间可能相交或包含。
小翔认为,一幅地图中最高的一列与最低的一列的高度差越大,这幅地图就越美观。
小翔可以选择m个魔法中的任意一些魔法来实施,使得地图尽量美观。但是他不知道该如何选择魔法,于是他找到了你。请你求出所有可行方案中,高度差的最大值。
对于100%的数据,满足1≤n,m≤200000,-109≤Hi≤109,1≤Wi≤109,1≤Li≤Ri≤n。

输入描述:

输入文件的第一行包含两个整数n,m。
输入的第二行包含n个整数,相邻两数间用一个空格隔开,第i个整数为H
i

接下来的m行,每行包含3个整数,分别是L
i
,R
i
,W
i
,相邻两数间用一个空格隔开。

输出描述:

一行一个整数,表示高度差的最大值。
示例1

输入

复制
3 3
7 -2 -10
1 3 4
3 3 4
1 2 8

输出

复制
21

分析

思维

对于每个点 i ,如果 i 是最小值,修改 i 点会使最小值更小,如果最大值 j 点在区间里面,不会改变最小值和最大值的差距,如果最大值不在里面,那可以增大最小值和最大值的差距

所以枚举每个点 i ,如果有区间的左端点是 i ,那全部修改,如果有区间的右端点 是 i 那全部返回到初始状态。

//-------------------------代码----------------------------

#define int ll
const int N = 2e5+10;
int n,m;

struct node {
    int l,r,mx,mn,lazy;
} tr[N<<2];
struct ty {
    int l,r,w;
};
int a[N];
V<ty> l[N],r[N];

void up(int u) {
    tr[u].mx = max(tr[ul].mx,tr[ur].mx);
    tr[u].mn = min(tr[ul].mn,tr[ur].mn);
}

void build(int u,int l,int r) {
    
    tr[u] = {l,r};
    tr[u].lazy = 0;
    if(l == r) {
        tr[u].mx = tr[u].mn = a[l];rt;
    }
    build(ul,l,tr_mid);build(ur,tr_mid+1,r);
    up(u);
}
void upt(int u,int x) {
    tr[u].mn += x;
    tr[u].mx += x;
    tr[u].lazy += x;
}

void push_down(int u) {
    if(tr[u].lazy) {
        upt(ul,tr[u].lazy);
        upt(ur,tr[u].lazy);
        tr[u].lazy = 0;
    }
}
void modify(int u,int l,int r,int v) {
    if(l <= tr[u].l && tr[u].r <= r) {
        upt(u,v);rt;
    }
    push_down(u);
    if(l <= tr_mid)modify(ul,l,r,v);
    if(tr_mid < r) modify(ur,l,r,v);
    up(u);
}
void solve()
{
    cin>>n>>m;
    int mx = -inf,mn = inf;
    fo(i,1,n) cin>>a[i],mx = max(mx,a[i]),mn = min(mn,a[i]);
    build(1,1,n);
    int ans = mx - mn;
    ty p;
    fo(i,1,m) {
        cin>>p.l>>p.r>>p.w;
        l[p.l].pb(p);
        r[p.r].pb(p);
    }
    fo(i,1,n) {
        int llen = l[i].size();
        int rlen = r[i].size();
        fo(j,0,llen-1) {
            modify(1,l[i][j].l,l[i][j].r,-l[i][j].w);
        }
        ans = max(ans,tr[1].mx - tr[1].mn);
        fo(j,0,rlen-1) {
            modify(1,r[i][j].l,r[i][j].r,r[i][j].w);
        }
    }
    cout<<ans<<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-13 17:30  er007  阅读(64)  评论(0)    收藏  举报