线段树[模板]最大连续子段和以及单节点修改 洛谷SP1716 GSS3 - Can you answer these queries III

//SegmenTree
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=200500;
struct Tree
{
int bond[2];
int lazy;
int son[2];
int sum;
int mks[3];
}tree[M];
int n,m,root=0,cnt=1;
int num[M];
int ans,que;
void pushup(int x)//更新节点
{
int lson=tree[x].son[0];
int rson=tree[x].son[1];
tree[x].mks[0]=max(tree[lson].mks[0],tree[lson].sum+tree[rson].mks[0]);
tree[x].mks[1]=max(tree[rson].mks[1],tree[rson].sum+tree[lson].mks[1]);
tree[x].mks[2]=max(tree[rson].mks[0]+tree[lson].mks[1],max(tree[lson].mks[2],tree[rson].mks[2]));
tree[x].sum=tree[lson].sum+tree[rson].sum;
tree[x].bond[0]=tree[lson].bond[0];
tree[x].bond[1]=tree[rson].bond[1];
return ;
}
void change(int poi,int val,int cur)
{
if (tree[cur].bond[0]==tree[cur].bond[1])
{
tree[cur].sum=val;
tree[cur].mks[2]=tree[cur].mks[1]=tree[cur].mks[0]=val;
return ;
}
int mid=(tree[cur].bond[0]+tree[cur].bond[1])>>1;
if (poi<=mid) change(poi,val,tree[cur].son[0]);
else change(poi,val,tree[cur].son[1]);
pushup(cur);
return ;
}
void built(int L,int R,int cur)
{
if (L==R)
{
tree[cur].son[0]=tree[cur].son[1]=-1;
tree[cur].bond[0]=tree[cur].bond[1]=L;
tree[cur].sum=num[L];
tree[cur].mks[0]=tree[cur].mks[1]=tree[cur].mks[2]=num[R];
tree[cur].lazy=0;
return ;
}
int mid=(L+R)>>1;
tree[cur].son[0]=cnt++;
tree[cur].son[1]=cnt++;
built(L,mid,tree[cur].son[0]);
built(mid+1,R,tree[cur].son[1]);
pushup(cur);
return ;
}
void query(int L,int R,int cur)
{
if (L<=tree[cur].bond[0]&&tree[cur].bond[1]<=R)
{
ans=max(ans,max(tree[cur].mks[2],tree[cur].mks[0]+que));
que=max(que+tree[cur].sum,tree[cur].mks[1]);
return ;
}
int mid=(tree[cur].bond[0]+tree[cur].bond[1])>>1;
if (L<=mid) query(L,R,tree[cur].son[0]);
if (R>mid) query(L,R,tree[cur].son[1]);
return ;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&num[i]);
built(1,n,root);
scanf("%d",&m);
while (m--)
{
int flag,l,r;
scanf("%d %d %d",&flag,&l,&r);
if (flag)
{
ans=-1e9;
que=ans;
query(l,r,root);
cout<<ans<<endl;
}
else change(l,r,root);
}
return 0;
}