1035 小翔和泰拉瑞亚 线段树 区间修改使最小值最大值差距最大 思维
链接:https://ac.nowcoder.com/acm/contest/26896/1035
来源:牛客网
题目描述
小翔爱玩泰拉瑞亚 。
一天,他碰到了一幅地图。这幅地图可以分为n列,第i列的高度为Hi,他认为这个地图不好看,决定对它进行改造。
小翔又学会了m个魔法,实施第i个魔法可以使地图的第Li列到第Ri列每一列的高度减少Wi,每个魔法只能实施一次,魔法的区间可能相交或包含。
小翔认为,一幅地图中最高的一列与最低的一列的高度差越大,这幅地图就越美观。
一天,他碰到了一幅地图。这幅地图可以分为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。i
输入的第二行包含n个整数,相邻两数间用一个空格隔开,第i个整数为H
。i
接下来的m行,每行包含3个整数,分别是L
,Ri
,Wi
,相邻两数间用一个空格隔开。
输出描述:
一行一个整数,表示高度差的最大值。
分析
思维
对于每个点 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; } /*样例区 */ //------------------------------------------------------------

浙公网安备 33010602011771号