zoukankan      html  css  js  c++  java
  • 洛谷p1115 最大子段和

    题目链接:https://www.luogu.org/problem/P1115

    线段树求最大子段和

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 200005
    #define ll long long
    #define ls l,mid,rt<<1
    #define rs mid+1,r,rt<<1|1
    #define inf 0x3f3f3f3f
    int a[maxn],sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];
    //sum 区间和
    //msum 区间最大子段和
    //lsum 区间左端点开始的最大子段和
    //rsum 区间右端点开始的最大子段和
    
    inline void pushup(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),lsum[rt<<1|1]+rsum[rt<<1]);
        lsum[rt]=max(lsum[rt<<1],sum[rt<<1]+lsum[rt<<1|1]);
        rsum[rt]=max(rsum[rt<<1|1],sum[rt<<1|1]+rsum[rt<<1]);
    }
    inline void build(int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]=msum[rt]=lsum[rt]=rsum[rt]=a[l];
            return ;
        }
        int mid=l+r>>1;
        build(ls);build(rs);
        pushup(rt);
    }
    inline int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&R>=r)return msum[rt];
        int ans=-inf,mid=l+r>>1;
        if(L<=mid)ans=max(ans,query(L,R,ls));
        if(R>mid)ans=max(ans,query(L,R,rs));
        return ans;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        build(1,n,1);
        cout<<query(1,n,1,n,1)<<endl;
        return 0;
    }
  • 相关阅读:
    网络安全协议(1)
    CG-CTF(6)
    CG-CTF(5)
    CG-CTF(4)
    CG-CTF(3)
    MAC地址欺骗(原理及实验)
    CG-CTF(2)
    CG-CTF(1)
    【转载】Spring Boot【快速入门】2019.05.19
    【编程大系】Java资源汇总
  • 原文地址:https://www.cnblogs.com/chen99/p/11327155.html
Copyright © 2011-2022 走看看