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;
    }
  • 相关阅读:
    c语言|博客作业05
    C语言I博客作业04
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    学期总结
    我的第一周C语言作业
    C语言I博客作业08
    C语言I博客作业07
  • 原文地址:https://www.cnblogs.com/chen99/p/11327155.html
Copyright © 2011-2022 走看看