• POJ 2750 Potted Flower


    传送门

    大半年时间没练习,已经什么也不会了 ==

    为了维护区间最大子区间和,容易想到线段树区间合并,需要维护包含左/右端点的最大子区间和。

    至于环状结构,可以通过二选一来等价得到答案,因此还需要维护区间最小子区间和。

    注意特判不能全选。

    #include <algorithm>
    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    const int maxn(1e5 + 10);
    int a[maxn];
    
    struct node {
        // 左(右)子编号,区间和
        int l, r, sum;
        // 区间内的最小(大)子区间和
        int mn, mx;
        // 区间内包含左端的最小(大)子区间和
        int lmn, lmx;
        // 区间内包含右端的最小(大)子区间和
        int rmn, rmx;
    } tree[maxn << 2];
    
    inline int ls(int cur) {
        return cur << 1;
    }
    
    inline int rs(int cur) {
        return cur << 1 xor 1;
    }
    
    void push_up(int cur) {
        tree[cur].sum = tree[ls(cur)].sum + tree[rs(cur)].sum;
        // 继承左子或右子拼接左子
        tree[cur].lmn = min(tree[ls(cur)].lmn, tree[rs(cur)].lmn + tree[ls(cur)].sum);
        tree[cur].lmx = max(tree[ls(cur)].lmx, tree[rs(cur)].lmx + tree[ls(cur)].sum);
        // 继承右子或左子拼接右子
        tree[cur].rmn = min(tree[rs(cur)].rmn, tree[ls(cur)].rmn + tree[rs(cur)].sum);
        tree[cur].rmx = max(tree[rs(cur)].rmx, tree[ls(cur)].rmx + tree[rs(cur)].sum);
        // 继承左右子或左右子拼接
        tree[cur].mn = min(min(tree[ls(cur)].mn, tree[rs(cur)].mn), tree[ls(cur)].rmn + tree[rs(cur)].lmn);
        tree[cur].mx = max(max(tree[ls(cur)].mx, tree[rs(cur)].mx), tree[ls(cur)].rmx + tree[rs(cur)].lmx);
    }
    
    void build(int cur, int l, int r) {
        tree[cur].l = l;
        tree[cur].r = r;
        if (l == r) {
            tree[cur].sum = tree[cur].mn = tree[cur].mx = 
                tree[cur].lmn = tree[cur].lmx = tree[cur].rmn = tree[cur].rmx = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(ls(cur), l, mid);
        build(rs(cur), mid + 1, r);
        push_up(cur);
    }
    
    void update(int cur, int p, int v) {
        if (tree[cur].l == p and tree[cur].r == p) {
            tree[cur].sum = tree[cur].mn = tree[cur].mx = 
                tree[cur].lmn = tree[cur].lmx = tree[cur].rmn = tree[cur].rmx = v;
            return;
        }
        int mid = (tree[cur].l + tree[cur].r) >> 1;
        if (p <= mid) {
            update(ls(cur), p, v);
        } else {
            update(rs(cur), p, v);
        }
        push_up(cur);
    }
    
    int query() {
        int mx = max(tree[1].mx, tree[1].sum - tree[1].mn);
        // 不能全选
        return mx == tree[1].sum ? mx - tree[1].mn : mx;
    }
    
    int main() {
    #ifdef ONLINE_JUDGE
    #else
        freopen("input.txt", "r", stdin);
    #endif
        int n, m, p, v;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        build(1, 1, n);
        scanf("%d", &m);
        while (m--) {
            scanf("%d%d", &p, &v);
            update(1, p, v);
            printf("%d
    ", query());
        }
        return 0;
    }
    
  • 相关阅读:
    POJ 2584 T-Shirt Gumbo (二分图多重最大匹配)
    POJ 2584 T-Shirt Gumbo (二分图多重最大匹配)
    POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
    POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
    HDU 4638 Group ★(树状数组)
    HDU 4638 Group ★(树状数组)
    HDU 4632 Palindrome subsequence (区间DP)
    HDU 4632 Palindrome subsequence (区间DP)
    hdu2604 Queuing
    poj3757 Training little cats
  • 原文地址:https://www.cnblogs.com/singularity2u/p/15097079.html
Copyright © 2020-2023  润新知