Can you answer these queries III (the maximum sub-segment sum of the interval)
Blue book title Can you answer these queries III
Given a sequence A of length N, and M instructions (N≤500000, M≤100000), each instruction may be one of the following two:
- "2 xy", change A[x] to y.
- "1 xy", query the largest continuous sub-segment sum in the interval [x,y], that is, max(x≤l≤r≤y)∑ri=lA[i].
For each query, output an integer to indicate the answer.
Idea: In the
online segment tree, except for the interval endpoints, in the maintenance interval and sum sums u m , the largest sub-segment of the interval anddat datd a t , the largest continuous sub-segment at the left end andlmax lmaxl m a x , the largest continuous sub-segment at the right end andrmax rmaxr m a x
transfer equation changes:
sum (p) = sum (p ∗ 2) + sum (p ∗ 2 + 1) sum(p)=sum(p*2)+sum(p*2+1)s u m ( p )=s u m ( p∗2)+s u m ( p∗2+1)
r m a x ( p ) = m a x ( r m a x ( p ∗ 2 + 1 ) , s u m ( p ∗ 2 + 1 ) + r m a x ( p ∗ 2 ) ) rmax(p)=max(rmax(p*2+1),sum(p*2+1)+rmax(p*2)) rmax(p)=max(rmax(p∗2+1),s u m ( p∗2+1)+rmax(p∗2))
l m a x ( p ) = m a x ( l m a x ( p ∗ 2 ) , l m a x ( p ∗ 2 + 1 ) + s u m ( 2 ∗ p ) ) lmax(p)=max(lmax(p*2),lmax(p*2+1)+sum(2*p)) lmax(p)=max(lmax(p∗2),lmax(p∗2+1)+sum(2∗p))
d a t ( p ) = m a x ( d a t ( p ∗ 2 ) , m a x ( d a t ( p ∗ 2 + 1 ) , l m a x ( p ∗ 2 + 1 ) + r m a x ( p ∗ 2 ) ) ) dat(p)=max(dat(p*2),max(dat(p*2+1),lmax(p*2+1)+rmax(p*2))) d a t ( p )=m a x ( d a t ( p∗2),m a x ( d a t ( p∗2+1),lmax(p∗2+1)+rmax(p∗2)))
struct SegmentTree{
int l,r;
int dat,sum,lmax,rmax;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define dat(x) tree[x].dat
#define sum(x) tree[x].sum
#define lmax(x) tree[x].lmax
#define rmax(x) tree[x].rmax
}tree[maxn*4];
int a[maxn];
int n,m;
void build(int p,int l,int r){
l(p)=l,r(p)=r;
if(l==r){
dat(p)=a[l];sum(p)=a[l];lmax(p)=a[l];rmax(p)=a[l];return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
sum(p)=sum(p*2)+sum(p*2+1);
rmax(p)=max(rmax(p*2+1),sum(p*2+1)+rmax(p*2));
lmax(p)=max(lmax(p*2),lmax(p*2+1)+sum(2*p));
dat(p)=max(dat(p*2),max(dat(p*2+1),lmax(p*2+1)+rmax(p*2)));
}
void change(int p,int x,int z){
if(l(p)==r(p)){
dat(p)=z;sum(p)=z;lmax(p)=z;rmax(p)=z;return;
}
int mid=(l(p)+r(p))/2;
if(x<=mid) change(p*2,x,z);
else change(p*2+1,x,z);
sum(p)=sum(p*2)+sum(p*2+1);
rmax(p)=max(rmax(p*2+1),sum(p*2+1)+rmax(p*2));
lmax(p)=max(lmax(p*2),lmax(p*2+1)+sum(2*p));
dat(p)=max(dat(p*2),max(dat(p*2+1),lmax(p*2+1)+rmax(p*2)));
}
SegmentTree ask(int p,int l,int r){
if(l<=l(p)&&r>=r(p)) return tree[p];
SegmentTree a,b,ans;
a.sum=a.lmax=a.rmax=a.dat=b.sum=b.lmax=b.rmax=b.dat=-1*inf;
ans.sum=0;
int mid=(l(p)+r(p))/2;
if(l<=mid){
a=ask(p*2,l,r);ans.sum+=a.sum;}
if(r>mid){
b=ask(p*2+1,l,r);ans.sum+=b.sum;}
ans.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
ans.lmax=max(a.lmax,a.sum+b.lmax);
ans.rmax=max(b.rmax,b.sum+a.rmax);
if(l>mid)ans.lmax=max(ans.lmax,b.lmax);
if(r<=mid)ans.rmax=max(ans.rmax,a.rmax);
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
while(m--){
int op,x,y;
cin>>op>>x>>y;
if(op==2){
change(1,x,y);
}
else {
if(x>y)swap(x,y);cout<<ask(1,x,y).dat<<endl;}
}
}