• spoj 1716...动态区间的最大连续子段和问题...点修改...


    比较经典的segment tree的应用,线段树中信息的巧妙设计能够使得整个区间的解可以由合并子区间的解得到,本题很好的体现了这一点。

    #include <stdio.h>
    #include <string.h>
    
    const int MAXN = 50005;
    
    typedef struct {
        int sum;        //[l..r]的所有元素和
        int prefix;     //[l..r]的最大前缀和
        int suffix;     //[l..r]的最大后缀和
        int max;        //[l..r]的最大子段和
        int l;
        int r;
    }Node;
    
    Node seg[MAXN * 3];
    int a[MAXN];
    int N,M;
    
    int fmax(int a,int b)
    {
        return a > b ? a : b;
    }
    
    void up(int num)
    {
        //bottom-up的递推过程
        seg[num].sum = seg[num << 1].sum + seg[num << 1 | 1].sum;
        seg[num].prefix = fmax(seg[num << 1].prefix, seg[num << 1].sum + seg[num << 1 | 1].prefix);
        seg[num].suffix = fmax(seg[num << 1 | 1].suffix, seg[num << 1 | 1].sum + seg[num << 1].suffix);
        seg[num].max = fmax(fmax(seg[num << 1].max, seg[num << 1 | 1].max), seg[num << 1].suffix + seg[num << 1 | 1].prefix);
    }
    
    void build(int num,int l,int r)
    {
        seg[num].l = l;
        seg[num].r = r;
    
        if ( l == r )
        {
            seg[num].sum = seg[num].prefix = seg[num].suffix = seg[num].max = a[l];
            return;
        }
    
        int m = ( l + r ) >> 1;
        build(num << 1, l, m);
        build(num << 1 | 1, m + 1, r);
        up(num);
    }
    
    void update(int num,int id,int value)
    {
        if ( seg[num].l == id && seg[num].r == id )
        {
            seg[num].sum = seg[num].prefix = seg[num].suffix = seg[num].max = value;
            return;
        }
    
        int m = ( seg[num].l + seg[num].r ) >> 1;
        if ( id <= m )
            update(num << 1, id, value);
        else
            update(num << 1 | 1, id, value);
    
        up(num);
    }
    
    int query_sum(int num,int l,int r)
    {
        if ( seg[num].l == l && seg[num].r == r )
            return seg[num].sum;
    
        int m = ( seg[num].l + seg[num].r ) >> 1;
        if ( r <= m )
            return query_sum(num << 1, l, r);
        if ( m + 1 <= l )
            return query_sum(num << 1 | 1, l, r);
        else
            return query_sum(num << 1, l, m) + query_sum(num << 1 | 1, m + 1, r);
    }
    
    int query_prefix(int num,int l,int r)
    {
        //查询[l..r]的最大前缀和
        if ( seg[num].l == l && seg[num].r == r )
            return seg[num].prefix;
    
        int m = ( seg[num].l + seg[num].r ) >> 1;
        if ( r <= m )
            return query_prefix(num << 1, l, r);
        else if ( m + 1 <= l )
            return query_prefix(num << 1 | 1, l, r);
        else
            return fmax(query_prefix(num << 1, l, m),query_sum(num << 1, l, m) + query_prefix(num << 1 | 1, m + 1, r));
    }
    
    int query_suffix(int num,int l,int r)
    {
        //查询[l..r]的最大后缀和
        if ( seg[num].l == l && seg[num].r == r )
            return seg[num].suffix;
    
        int m = ( seg[num].l + seg[num].r ) >> 1;
        if ( r <= m )
            return query_suffix(num << 1, l, r);
        else if ( m + 1 <= l )
            return query_suffix(num << 1 | 1, l, r);
        else
            return fmax(query_suffix(num << 1 | 1, m + 1, r), query_sum(num << 1 | 1, m + 1, r) + query_suffix(num << 1, l, m));
    }
    
    int query(int num,int l,int r)
    {
        if ( seg[num].l == l && seg[num].r == r)
            return seg[num].max;
    
        int m = ( seg[num].l + seg[num].r ) >> 1;
        if ( r <= m )
            return query(num << 1, l, r);
        else if ( m + 1 <= l )
            return query(num << 1 | 1, l, r);
        else
        {
            int ans = fmax(query(num << 1, l, m), query(num << 1 | 1, m + 1, r));
            ans = fmax(ans, query_suffix(1, l, m) + query_prefix(1, m + 1, r));
            return ans;
        }
    }
    
    int main()
    {
    //    freopen("1.txt","r",stdin);
    
        scanf("%d",&N);
        for (int i = 1; i <= N; i++)
            scanf("%d",&a[i]);
    
        build(1,1,N);
    
        scanf("%d",&M);
    
        int u,v,w;
        while ( M-- )
        {
            scanf("%d%d%d",&u,&v,&w);
            if ( u == 0 )
            {
                a[v] = w;
                update(1,v,w);
            }
            else
                printf("%d
    ",query(1,v,w));
        }
    
        return 0;
    }
  • 相关阅读:
    第二阶段团队绩效评分
    团队冲刺2.9
    团队冲刺2.8
    团队冲刺2.7
    团队冲刺2.6
    团队冲刺2.5
    项目总结以及事后诸葛亮会议
    做什么都队第二阶段绩效评估
    第二阶段冲刺第十天
    第二阶段冲刺第九天
  • 原文地址:https://www.cnblogs.com/jiongjiong-mengmeng/p/3153892.html
Copyright © 2020-2023  润新知