Can you answer these queries III
You are given a sequence A of
N
N
N (
N
≤
50000
N \leq 50000
N≤50000) integers between
−
10000
-10000
−10000 and
10000
10000
10000. On this sequence you have to apply
M
M
M (
M
≤
50000
M \leq 50000
M≤50000) operations:
modify the i-th element in the sequence or for given
x
x
x
y
y
y print max{
A
i
+
A
i
+
1
+
.
.
+
A
j
A_i + A_{i+1} + .. + A_j
Ai+Ai+1+..+Aj
∣
|
∣
x
≤
i
≤
j
≤
y
x\leq i\leq j\leq y
x≤i≤j≤y }.
Input
The first line of input contains an integer
N
N
N. The following line contains
N
N
N integers, representing the sequence
A
1
.
.
A
N
A_1..A_N
A1..AN.
The third line contains an integer
M
M
M. The next
M
M
M lines contain the operations in following form:
0
0
0
x
x
x
y
y
y: modify
A
x
A_x
Ax into y (
∣
y
∣
|y|
∣y∣<=
10000
10000
10000).
1
1
1
x
x
x
y
y
y: print max{
A
i
+
A
i
+
1
+
.
.
+
A
j
A_i + A_i+1 + .. + A_j
Ai+Ai+1+..+Aj |
x
≤
i
≤
j
≤
y
x\leq i\leq j\leq y
x≤i≤j≤y }.
Output
For each query, print an integer as the problem required.
Example
Input:
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3
Output:
6
4
-3
思路
除了 l l l与 r r r之外,还需保存四个量: s u m , d a t , l m a x , r m a x sum,dat,lmax,rmax sum,dat,lmax,rmax。
更新方法如下:
t[p].sum=t[p*2].sum+t[p*2+1].sum; t[p].lmax=max(t[p*2].lmax,t[p*2].sum+t[p*2+1].lmax); t[p].rmax=max(t[p*2+1].rmax,t[p*2+1].sum+t[p*2].rmax); t[p].dat=max(max(t[p*2].dat,t[p*2+1].dat),t[p*2].rmax+t[p*2+1].lmax);
可以把更新的代码单独写到一个 u p d a t e update update函数中,增加代码复用。
一个坑点是,查询时 l l l可能大于 r r r。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=5e4+10;
struct T{int l,r,dat,sum,lmax,rmax;}t[maxn*4];
int n,m,a[maxn],op,x,y;
void update(T &c,T &a,T &b){
c.sum=a.sum+b.sum;
c.lmax=max(a.lmax,a.sum+b.lmax);
c.rmax=max(b.rmax,b.sum+a.rmax);
c.dat=max(max(a.dat,b.dat),a.rmax+b.lmax);
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){t[p].sum=t[p].dat=t[p].lmax=t[p].rmax=a[l];return;}
int mid=(l+r)/2;
build(p*2,l,mid),build(p*2+1,mid+1,r);
update(t[p],t[p*2],t[p*2+1]);
}
void change(int p,int x,int y){
if(t[p].l==t[p].r){t[p].sum=t[p].dat=t[p].lmax=t[p].rmax=y;return;}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid) change(p*2,x,y);
else change(p*2+1,x,y);
update(t[p],t[p*2],t[p*2+1]);
}
T ask(int p,int l,int r){
if(l>r) swap(l,r); //注意
if(l<=t[p].l&&r>=t[p].r) return t[p];
int mid=(t[p].l+t[p].r)/2;
if(r<=mid) return ask(p*2,l,r);
else if(l>=mid+1) return ask(p*2+1,l,r);
else{
T a,b,c;
a=ask(p*2,l,r),b=ask(p*2+1,l,r);
update(c,a,b);
return c;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&op,&x,&y);
if(op==0) change(1,x,y);
else printf("%d\n",ask(1,x,y).dat);
}
}