线段树裸题。
注意:更新的操作一定要在修改之后再进行,否则最大值变小后无法更新。
#include <bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define lch (now<<1)
#define rch ((now<<1)+1)
#define fa (now>>1)
const int maxn = 100010;
typedef long long ll;
ll tree[maxn*5], lazy[maxn*5];
void down(int now){
if(!lazy[now]) return;
lazy[lch] += lazy[now];
lazy[rch] += lazy[now];
tree[lch] += lazy[now];
tree[rch] += lazy[now];
lazy[now] = 0;
}
void build(int now, int l, int r){
if(l == r){
scanf("%lld", &tree[now]);
return;
}
build(lch, l, mid);
build(rch, mid+1, r);
tree[now] = max(tree[lch], tree[rch]);
}
void modify(int now, int l, int r, int pos1, int pos2, int change){
if(l == pos1 && r == pos2){
lazy[now] += change;
tree[now] += change;
return;
}
down(now);
if(pos2 <= mid) modify(lch, l, mid, pos1, pos2, change);
else if(pos1 >= mid+1) modify(rch, mid+1, r, pos1, pos2, change);
else modify(lch, l, mid, pos1, mid, change),
modify(rch, mid+1, r, mid+1, pos2, change);
tree[now] = max(tree[lch], tree[rch]);
}
ll que(int now, int l, int r, int pos1, int pos2){
if(l == pos1 && r == pos2) return tree[now];
down(now);
if(pos2 <= mid) return que(lch, l, mid, pos1, pos2);
else if(pos1 >= mid+1) return que(rch, mid+1, r, pos1, pos2);
else return max(que(lch, l, mid, pos1, mid), que(rch, mid+1, r, mid+1, pos2));
}
int main(){
int n, m;
scanf("%d", &n);
build(1, 1, n);
scanf("%d", &m);
for(int i = 1; i <= m; i ++){
int a, b, c, d;
scanf("%d", &a);
if(a == 1){
scanf("%d%d%d", &b, &c, &d);
modify(1, 1, n, b, c, d);
}else{
scanf("%d%d", &b, &c);
printf("%lld\n", que(1, 1, n, b, c));
}
}
return 0;
}