zoukankan      html  css  js  c++  java
  • [模板] 动态修改最大子段和

    link

    建一棵线段树,一个节点维护$4$个东西,最大前缀和,最大后缀和,最大连续和,总的权值和,先说最大前缀和怎么进行维护,我们只需看一看左儿子的最大前缀和,但是有可能终点不止包含左节点的所有,还有可能有右节点的最长前缀和,所以就将左儿子的所有权值加上右儿子的最长前缀和,然后其他都是这样处理。在查询中有可能右端点在$mid$的右面,所以需要特判取最优解

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    struct node{
        int ans,ls,rs,sum;
    }xx[2000001];
    int n,m,val[2000001];
    void pushdown(int x){
        xx[x].sum=xx[x<<1].sum+xx[x<<1|1].sum;
        xx[x].ls=max(xx[x<<1].ls,xx[x<<1].sum+xx[x<<1|1].ls);
        xx[x].rs=max(xx[x<<1|1].rs,xx[x<<1|1].sum+xx[x<<1].rs);
        xx[x].ans=max(xx[x<<1].ans,max(xx[x<<1|1].ans,xx[x<<1].rs+xx[x<<1|1].ls));
        return;
    }
    void build(int k,int l,int r){
        if(l==r){
            xx[k].ls=xx[k].rs=xx[k].ans=xx[k].sum=val[l];
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid),build(k<<1|1,mid+1,r);
        pushdown(k);
        return;
    }
    void change(int k,int l,int r,int x,int y,int w){
        if(x<=l&&r<=y){
            xx[k].ls=xx[k].rs=xx[k].ans=xx[k].sum=w;
            return;
        }
        int mid=l+r>>1;
        if(x<=mid) change(k<<1,l,mid,x,y,w);
        if(mid<y) change(k<<1|1,mid+1,r,x,y,w);
        pushdown(k);
        return;
    }
    node query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y) {
            return xx[k];
        }
        int mid=l+r>>1;
        if(x<=mid&&!(mid<y)) return query(k<<1,l,mid,x,y);
        else if(!(x<=mid)&&mid<y) return query(k<<1|1,mid+1,r,x,y);
        else{
            
            node st,t1=query(k<<1,l,mid,x,y),t2=query(k<<1|1,mid+1,r,x,y);
            st.sum=t1.sum+t2.sum;
            st.ls=max(t1.ls,t1.sum+t2.ls);
             st.rs=max(t2.rs,t2.sum+t1.rs);
            st.ans=max(t1.ans,max(t2.ans,t1.rs+t2.ls));
            return st;
        }
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++) val[i]=read();
        build(1,1,n);
        while(m--){
            int pd=read();
            if(pd==2){
                int x=read(),w=read();
                change(1,1,n,x,x,w);
            }
            else if(pd==1){
                int l=read(),r=read();
                if(l>r) swap(l,r);
                printf("%d
    ",query(1,1,n,l,r).ans);
            }
        }
    }
    View Code
  • 相关阅读:
    四级英语day9
    123
    像程序员一样思考
    Kali
    OS X
    Effective Java
    DHU ACM OJ
    Ambari
    Hadoop
    Hadoop2
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/9858274.html
Copyright © 2011-2022 走看看