[vijos 1083] Xiaobaiwan Park
describe
Xiao Xin often accompanies Xiao Bai to play in the park, which is the so-called dog walk. There is a "Park Road" near Xiaoxinjia. On one side of the road, there are n parks in turn from south to north. Xiaobai has looked at them for a long time, and he does not know which parks to visit.
From the beginning, Xiao Bai scored each park according to its scenery -. -. In order to save time, Xiao Xin will prescribe a range in advance when he walks his dog. Xiao Bai can only choose between parks a and B (including parks a and b) and choose consecutive parks to play in. Xiao Bai of course hopes that the total score of the selected park will be as high as possible. At the same time, because the landscape of some parks will change, Xiaobai's score may also change.
Then, please come and help Xiaobai choose the park.
Input format
The first line, two integers N and M, denote the number of parks and the total number of operations (walking dogs or changing scores), respectively.
Next, N lines, an integer for each line, give the park's score at the beginning of Xiaobai in turn.
Next M lines, three integers per line. The first integer K, 1 or 2. K=1 means Xiao Xin will take Xiao Bai out to play. The next two integers a and B give the scope of choosing the park (1 < a,b < N, a can be larger than b!). K=2 indicates that Xiaobai changed the score of a park, and the next two integers P and s indicate that Xiaobai changed the score of the park to s (1 < p < N).
Among them, 1 < N < 500 000, 1 < M < 100 000, all scores are integers with absolute value not exceeding 1000.
Output format
Every time Xiao Bai goes out to play, he outputs a line corresponding to the output, which contains only one integer, indicating the maximum score and sum of the park that Xiao Bai can choose.
Analysis: Nude segment tree maintenance interval sum can be used as a template. Note that tr has four markers. ml represents the maximum sum from the left, mr is the maximum field sum from the right, mx is the maximum continuous field sum in the interval, and sum is the interval sum. Then it is not difficult to see such maintenance:
sum[h] = sum[h << 1] + sum[h << 1|1];
ml[h]= max(ml[h<<1],sum[h<<1]+ml[h<<1|1]);
mr[h]=max(mr[h<<1|1],sum[<<1|1]+mr[h<<1]; mx[h]=max(max(mx[h<<1],mx[h<<1|1]),ml[h<<1|1]+mr[h<<1]);
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <queue>
# include <cmath>
# include <vector>
using namespace std;
int read(){
register int f=1,i=0;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {i=(i<<3)+(i<<1)+ch-'0';ch=getchar();}
return f*i;
}
const int N=2000000+10;
struct node{
int ml,mr,mx,sum;
node(){};
node(int ml,int mr,int mx,int sum) : ml(ml),mr(mr),mx(mx),sum(sum){}
}tr[N];
int n,m,x,y,z,k,a[N];
struct seg{
inline void change(int k){
tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
tr[k].ml=max(tr[k<<1].ml,tr[k<<1].sum+tr[k<<1|1].ml);
tr[k].mr=max(tr[k<<1|1].mr,tr[k<<1|1].sum+tr[k<<1].mr);
tr[k].mx=max(max(tr[k<<1].mx,tr[k<<1|1].mx),tr[k<<1].mr+tr[k<<1|1].ml);
}
inline void build(int k,int l,int r){
if(l==r){
tr[k].sum=tr[k].mx=tr[k].ml=tr[k].mr=a[l];
return;
}
int mid=l+r>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r);
change(k);
}
inline void update(int k,int l,int r,int pos,int x){
if(l==r){
tr[k].sum=tr[k].mx=tr[k].ml=tr[k].mr=x;
return;
}
int mid=l+r>>1;
if(pos<=mid) update(k<<1,l,mid,pos,x);
if(pos>mid) update(k<<1|1,mid+1,r,pos,x);
change(k);
}
node query(int k,int l,int r,int s,int t){
if(s==l&&r==t){
node tmp=node(tr[k].ml,tr[k].mr,tr[k].mx,tr[k].sum);
return tmp;
}
int mid=l+r>>1;
if(t<=mid) return query(k<<1,l,mid,s,t);
else if(s>mid) return query(k<<1|1,mid+1,r,s,t);
node a,b,tmp;
a=query(k<<1,l,mid,s,mid);
b=query(k<<1|1,mid+1,r,mid+1,t);
tmp.mx=max(max(a.mx,b.mx),a.mr+b.ml);
tmp.ml=max(a.ml,a.sum+b.ml);
tmp.mr=max(b.mr,b.sum+a.mr);
return tmp;
}
}Seg;
int main(){
freopen("lx.in","r",stdin);
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
Seg.build(1,1,n);
for(int i=1;i<=m;++i){
k=read();
if(k==1){
x=read(),y=read();
if(x > y)swap(x,y);
printf("%d\n",Seg.query(1,1,n,x,y).mx);
}else{
x=read(),y=read();
Seg.update(1,1,n,x,y);
}
}
}