线段树
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,q;
struct node{
int l,r;
int sum;
int amax,amin; //区间最大、小序列和
int lmax,rmax; //区间最左、右连续最大和
int lmin,rmin; //区间最左、右连续最小和
}tree[300000];
void build(int s,int t,int id){
tree[id].l=s,tree[id].r=t;
tree[id].sum=0;
tree[id].amax=tree[id].lmax=tree[id].rmax=-1000000000;
tree[id].amin=tree[id].lmin=tree[id].rmin= 1000000000;
if(s!=t){
int mid=(s+t)>>1;
build(s,mid,id*2);
build(mid+1,t,id*2+1);
}
}
void updatelength(int id){
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
tree[id].amax=max(max(tree[id*2].amax,tree[id*2+1].amax),tree[id*2].rmax+tree[id*2+1].lmax);
tree[id].amin=min(min(tree[id*2].amin,tree[id*2+1].amin),tree[id*2].rmin+tree[id*2+1].lmin);
tree[id].lmax=tree[id*2].lmax;
tree[id].lmin=tree[id*2].lmin;
tree[id].rmax=tree[id*2+1].rmax;
tree[id].rmin=tree[id*2+1].rmin;
if(tree[id*2].lmax<tree[id*2].sum+tree[id*2+1].lmax) //注意在更新tree[id*2].lmax等这四个变量时有一些问题
tree[id].lmax=tree[id*2].sum+tree[id*2+1].lmax;
if(tree[id*2].lmin>tree[id*2].sum+tree[id*2+1].lmin)
tree[id].lmin=tree[id*2].sum+tree[id*2+1].lmin;
if(tree[id*2+1].rmax<tree[id*2+1].sum+tree[id*2].rmax)
tree[id].rmax=tree[id*2+1].sum+tree[id*2].rmax;
if(tree[id*2+1].rmin>tree[id*2+1].sum+tree[id*2].rmin)
tree[id].rmin=tree[id*2+1].sum+tree[id*2].rmin;
}
void update(int s,int tem,int id){
if(tree[id].l==tree[id].r){
tree[id].sum=tem;
tree[id].amax=tree[id].amin=tree[id].lmax=tree[id].lmin=tree[id].rmax=tree[id].rmin=tem;
return ;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=s)
update(s,tem,id*2);
else
update(s,tem,id*2+1);
updatelength(id);
}
int main(){
int i,j,pos,tem;
scanf("%d",&n);
build(1,n,1);
for(i=1;i<=n;i++){
scanf("%d",&tem);
update(i,tem,1);
}
scanf("%d",&q);
for(i=1;i<=q;i++){
scanf("%d %d",&pos,&tem);
update(pos,tem,1);
if(tree[1].amax==tree[1].sum)
printf("%d\n",tree[1].amax-tree[1].amin);
else if(tree[1].amax>=tree[1].sum-tree[1].amin) //考虑到环的性质,最左边的线段连接最右边的线段这种情况也可能产生最大值
printf("%d\n",tree[1].amax);
else if(tree[1].amax<tree[1].sum-tree[1].amin) //但是此时最大值为环总和减去最小连续和,而不是tree[1].lmax+tree[1].rmax
printf("%d\n",tree[1].sum-tree[1].amin);
}
}