• LA 3938 动态最大连续区间 线段树


    思路很清晰,实现很繁琐。分析过程可以参考LRJ,自己的总结晚些放。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxN=5e5+5,maxNode=1e6+5;
    #define ll long long
    #define Seg pair<int,int>
    #define fi first
    #define se second
    
    #define lson l,m,rt*2
    #define rson m+1,r,rt*2+1
    
    ll prefix_sum[maxN];
    ll sum(int L, int R) {return prefix_sum[R] - prefix_sum[L - 1];}
    ll sum(Seg p) {return sum(p.fi, p.se);}
    Seg better(Seg a, Seg b) {
        if (sum(a) !=  sum(b)) return sum(a) > sum(b) ? a : b;
        else return a < b ? a : b;
    }
    
    int qL, qR;
    
    struct SegTree {
        int max_prefix[maxNode];
        int max_suffix[maxNode];
        Seg max_sub[maxNode];
    
        void build(int l, int r, int rt) {
            if (l == r) {
                max_prefix[rt] = max_suffix[rt] = l;
                max_sub[rt] = make_pair(l, l);
                return;
            }
            int m = l + (r - l) / 2;
            int lch = rt * 2, rch = rt * 2 + 1;
            build(lson);
            build(rson);
    
            // push_up
            // 递推max_prefix
            ll v1 = sum(l, max_prefix[lch]);
            ll v2 = sum(l, max_prefix[rch]);
            if (v1 == v2) max_prefix[rt] = min(max_prefix[lch], max_prefix[rch]);
            else max_prefix[rt] = v1 > v2 ? max_prefix[lch] : max_prefix[rch];
    
            // 递推max_suffix
            v1 = sum(max_suffix[lch], r);
            v2 = sum(max_suffix[rch], r);
            if (v1 == v2) max_suffix[rt] = min(max_suffix[lch], max_suffix[rch]);
            else max_suffix[rt] = v1 > v2 ? max_suffix[lch] : max_suffix[rch];
    
            // 递推max_sub
            max_sub[rt] = better(max_sub[lch], max_sub[rch]);
            max_sub[rt] = better(max_sub[rt], make_pair(max_suffix[lch], max_prefix[rch]));
        }
        
        Seg query_prefix(int l, int r, int rt) {
            if (max_prefix[rt] <= qR) return make_pair(l, max_prefix[rt]);
            int m = (l + r) / 2;
            int lch = rt * 2;
            if (qR <= m) return query_prefix(lson);
            Seg i = query_prefix(rson);
            i.fi = l;
            return better(i, make_pair(l, max_prefix[lch]));
        }
        Seg query_suffix(int l, int r, int rt) {
            if (max_suffix[rt] >= qL) return make_pair(max_suffix[rt], r);
            int m = (l + r) / 2;
            int rch = 2 * rt + 1;
            if (qL > m) return query_suffix(rson);
            Seg i = query_suffix(lson);
            i.se = r;
            return better(i, make_pair(max_suffix[rch], r));
        }
        Seg query(int l, int r, int rt) {
            if (qL <= l && r <= qR) return max_sub[rt];
            int m = (l + r) / 2;
            if (qR <= m) return query(lson);
            if (qL > m) return query(rson);
            Seg i1 = query_prefix(rson);
            Seg i2 = query_suffix(lson);
            Seg i3 = better(query(lson), query(rson));
            return better(make_pair(i2.fi, i1.se), i3);
        }
    };
    
    SegTree tree;
    
    int main() {
        // freopen("data.in", "r", stdin);
        int kase = 0, n, a, Q;
        while (~scanf("%d%d", &n, &Q)) {
            prefix_sum[0] = 0;
            for (int i = 0; i < n; ++i) {
                scanf("%d", &a);
                prefix_sum[i + 1] = prefix_sum[i] + a;
            }
            tree.build(1, n, 1);
            printf("Case %d:
    ", ++kase);
            while (Q--) {
                int L, R;
                scanf("%d%d", &L, &R);
                qL = L, qR = R;
                Seg ans = tree.query(1, n, 1);
                printf("%d %d
    ", ans.fi, ans.se);
            }
        }
        return 0;
    }
  • 相关阅读:
    golang获取URL
    Golang读取HTML中Table数据到二维数组
    Golang的GUI开发包fyne基本教程
    C#搭建安川机器人上位机
    程序计数器
    SpringBoot定时任务详解
    mysql 5.7安装
    springboot 配置多数据源
    mysql 查询某一天数据
    java如何获取当前日期和时间
  • 原文地址:https://www.cnblogs.com/Rosebud/p/9545713.html
Copyright © 2020-2023  润新知