【算法】线段树
【题解】区间加上同一个数+区间查询最大值。注意和谐值可以是负数,初始化ans为负无穷大。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<algorithm> using namespace std; const int maxn=100010,ainf=-0x3f3f3f3f; struct treess{int l,r,ms,delta;}t[maxn*3]; int a[maxn],n,m; void build(int k,int l,int r) { t[k].l=l;t[k].r=r; if(l==r)t[k].ms=a[l]; else { int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); t[k].ms=max(t[k<<1].ms,t[k<<1|1].ms); } } void update(int k,int l,int r,int x) { int left=t[k].l,right=t[k].r; if(l<=left&&right<=r)t[k].delta+=x; else { int mid=(left+right)>>1; if(l<=mid)update(k<<1,l,r,x); if(r>mid)update(k<<1|1,l,r,x); t[k].ms=max(t[k<<1].ms+t[k<<1].delta,t[k<<1|1].ms+t[k<<1|1].delta); } } int ask(int k,int l,int r) { int left=t[k].l,right=t[k].r,ans=ainf; if(l<=left&&right<=r)ans=t[k].ms+t[k].delta; else { t[k].ms+=t[k].delta; t[k<<1].delta+=t[k].delta; t[k<<1|1].delta+=t[k].delta; t[k].delta=0; int mid=(left+right)>>1; if(l<=mid)ans=ask(k<<1,l,r); if(r>mid)ans=max(ans,ask(k<<1|1,l,r)); } return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); int l,r,c,k; for(int i=1;i<=m;i++) { scanf("%d",&k); if(k==1) { scanf("%d%d%d",&l,&r,&c); update(1,l,r,c); } else { scanf("%d%d",&l,&r); printf("%d\n",ask(1,l,r)); } } return 0; }