zoukankan      html  css  js  c++  java
  • [模板]維護區間最大子段和的線段樹

    其實把update看懂就很好說了,沒什麼特別難理解的

    luogu_P4513小白逛公園

    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define ls p<<1
    #define rs p<<1|1
    using namespace std;
    const int maxn=500005;
    int n,m;
    struct node{
        ll sum,mx,l,r;//包含左/右端点最大子段和 
    }t[maxn<<2];
    ll a[maxn];
    inline int max(int a,int b){return a<b?b:a;}
    void upd(int p){
        t[p].l=max(t[ls].l,t[ls].sum+t[rs].l);
        //选包含左边端点那段 或者把左半边全选上加上右半边包含左端点 
        t[p].r=max(t[rs].r,t[rs].sum+t[ls].r);
        t[p].mx=max( max(t[ls].mx,t[rs].mx),t[ls].r+t[rs].l);
        //这段的最大子段和 
        t[p].sum=t[ls].sum+t[rs].sum;
    }
    void build(int p,int l,int r)
    {
        if(l==r){
            t[p].sum=t[p].mx=t[p].l=t[p].r=a[l];return;
        }
        int mid=(l+r)/2;
        build(ls,l,mid);build(rs,mid+1,r);
        upd(p);
    }
    void change(int p,int l,int r,int pos,ll k)
    {
        if(l==r){
            t[p].mx=t[p].l=t[p].r=t[p].sum=k;return;
        }
        int mid=(l+r)/2;
        if(pos>mid)change(rs,mid+1,r,pos,k);
        else change(ls,l,mid,pos,k);
        upd(p);
    }
    node query(int p,int l,int r,int LL,int RR)//因为最大值不是直接取就行,所以传一个node 
    {
        if(l==LL && r==RR)return t[p];
        int mid=(l+r)/2;
        if(RR<=mid)return query(ls,l,mid,LL,RR);
        else if(LL>mid)return query(rs,mid+1,r,LL,RR);
        node x=query(ls,l,mid,LL,mid),y=query(rs,mid+1,r,mid+1,RR),ret;
        //和update道理一样 
        ret.l=max(x.l,x.sum+y.l);
        ret.r=max(y.r,y.sum+x.r);
        ret.mx=max( max(x.mx,y.mx),x.r+y.l );
        ret.sum=x.sum+y.sum;
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
    //    memset(t,0xcf,sizeof(t));
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        build(1,1,n);
        while(m--){
            int l,r;ll k;
            scanf("%lld%d%d",&k,&l,&r);
            if(k==1){
                if(l>r)swap(l,r);
                printf("%lld
    ",query(1,1,n,l,r).mx);
            }
            else change(1,1,n,l,r);
        }
    }
  • 相关阅读:
    Visual Studio Code插件安装步骤
    JS省城级联
    JS省城级联
    JS省城级联
    JS省城级联
    【JAVA零基础入门系列】Day9 Java中的那个大数值
    【JAVA零基础入门系列】Day9 Java中的那个大数值
    【JAVA零基础入门系列】Day9 Java中的那个大数值
    [js插件开发教程]实现一个比较完整的开源级选项卡插件
    VS2017桌面应用程序打包成.msi或者.exe
  • 原文地址:https://www.cnblogs.com/superminivan/p/10692604.html
Copyright © 2011-2022 走看看