得了一种看到高级数据结构就害怕的病

但我们还是要迎♂而上(雾

题意:有n个数,a[1]到a[n]。接下来q次操作,一种是将a[x]变为y,另一种是指定两个数l,r,求a[l]到a[r]的最大子段和。

思路

imgimgimg

img

gss的维护上面说到了;

lgss的维护:

1.左儿子的lgss 2.左儿子的sum+右儿子的lgss(如果跨过了左儿子区间,左边最长连续区间肯定要取到左区间的sum)。

rgss的维护:

1.右儿子的rgss 2.右儿子的sum+左儿子的rgg。

询问:

利用先遍历左儿子的性质。

ans:1.该区间的gss 2.之前所有区间的最大字段和+该区间的lgss。

所以设置一个变量pre用来记录之前所有区间的最大字段和。

pre的维护:1.该区间的rgss 2.pre+该区间的sum。

代码

#define INF 0x3f3f3f3f
#define nl id<<1
#define nr id<<1|1
struct Node
{
    int left,right;
    int sum;//区间和
    int gss;//最大子段和
    int lgss,rgss;//最大左右子段和
}node[50000<<2];
int ans,pre;
void up(int id)
{
    node[id].sum=node[nl].sum+node[nr].sum;
    node[id].gss=max(max(node[nl].gss,node[nr].gss),node[nl].rgss+node[nr].lgss);
    node[id].lgss=max(node[nl].lgss,node[nl].sum+node[nr].lgss);
    node[id].rgss=max(node[nr].rgss,node[nr].sum+node[nl].rgss);
}
void build(int l,int r,int id)
{
    node[id].left=l;node[id].right=r;
    if(l==r)
    {
        scanf("%d",&node[id].sum);
        node[id].lgss=node[id].rgss=node[id].gss=node[id].sum;
        return;
    }
    int m=(l+r)>>1;
    build(l,m,nl);build(m+1,r,nr);
    up(id);
}
void update(int loc,int c,int id)
{
    int l=node[id].left;int r=node[id].right;
    if(l==r)
    {
        node[id].sum=c;
        node[id].lgss=node[id].rgss=node[id].gss=node[id].sum;
        return;
    }
    int m=(l+r)>>1;
    if(loc<=m)update(loc,c,nl);
    else update(loc,c,nr);
    up(id);
}
void query(int L,int R,int id)
{
    int l=node[id].left;int r=node[id].right;
    if(l>=L&&r<=R)
    {
        ans=max(ans,max(node[id].gss,pre+node[id].lgss));
        pre=max(node[id].rgss,pre+node[id].sum);//之前所有区间的最大右字段和
        return;
    }
    int m=(l+r)>>1;
    if(L<=m)query(L,R,nl);
    if(R>m)query(L,R,nr);
}
int main()
{
    int n,q,ope,x,y;
    scanf("%d",&n);
    build(1,n,1);
    scanf("%d",&q);
    while(q--)
    {
        scanf("%d%d%d",&ope,&x,&y);
        if(ope==0)update(x,y,1);
        else if(ope==1)
        {
            ans=-INF;
            pre=-INF;
            query(x,y,1);
            printf("%d\n",ans);
        }
    }
    return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

SG函数 Previous
一天一dp Next