题意:在询问一段数列的连续最大自序列和的基础上又增加了单点修改
解法:单点修改还是很简单的吧 其实gss这两题主要是要从线段树的先序遍历进行思考就可以了
如果拓展一下LCIS能不能也这样做呢?我觉得也是可以的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 50005
#define inf 0x3f3f3f3f
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
int lm[maxn<<2],rm[maxn<<2],mm[maxn<<2],sum[maxn<<2];
int ans,pre;
void up(int rt){
sum[rt]=sum[ls]+sum[rs];
mm[rt]=max(mm[ls],mm[rs]);
lm[rt]=max(lm[ls],sum[ls]+max(0,lm[rs]));
rm[rt]=max(rm[rs],sum[rs]+max(0,rm[ls]));
mm[rt]=max(mm[rt],rm[ls]+lm[rs]);
}
void build(int rt,int l,int r){
if(l==r){
scanf("%d",&mm[rt]);
sum[rt]=lm[rt]=rm[rt]=mm[rt];
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
up(rt);
}
void ins(int rt,int l,int r,int L,int R,int w){
if(L<=l&&r<=R){
sum[rt]=mm[rt]=lm[rt]=rm[rt]=w;
return ;
}
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
up(rt);
}
void query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
ans=max(ans,mm[rt]);
ans=max(ans,pre+lm[rt]);
pre=max(rm[rt],pre+sum[rt]);
return;
}
if(L<=mid)query(ls,l,mid,L,R);
if(mid<R)query(rs,mid+1,r,L,R);
}
int main()
{
int n,m,a,b,op;
while(~scanf("%d",&n)){
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&op,&a,&b);
if(op){
ans=pre=-inf;
query(1,1,n,a,b);
printf("%d\n",ans);
}else{
ins(1,1,n,a,a,b);
}
}
}
return 0;
}