BZOJ 4636: 蒟蒻的数列

在修改操作和查询操作那里搞了好久。
标记在修改过程是不需要下传也不需要pushup的
只需要在最后查询的时候多开一个参数表示从根到当前节点的最大值,每次取max即可,若当前没有左儿子,说明左儿子都是这个值,右儿子同理

#include <bits/stdc++.h>
#define ll long long

const int N = 4e4 + 7;
const int ALL = 1e9 + 1;

ll sum;

struct Seg {
    #define lp tree[p].l
    #define rp tree[p].r
    struct Node {
        int l, r, v;
    } tree[N * 20];
    int tol;
    void update(int &p, int l, int r, int x, int y, int k) {
        if (!p) p = ++tol;
        if (x <= l && y >= r) {
            tree[p].v = std::max(tree[p].v, k);
            return;
        }
        int mid = l + r >> 1;
        if (x <= mid) update(tree[p].l, l, mid, x, y, k);
        if (y > mid) update(tree[p].r, mid + 1, r, x, y, k);
    }
    ll query(int p, int l, int r, int v) {
        if (!p) return 0;
        tree[p].v = std::max(tree[p].v, v);
        v = std::max(v, tree[p].v);
        ll ans = 0;
        int mid = l + r >> 1;
        if (lp) ans += query(lp, l, mid, v);
        else ans += 1LL * (mid - l + 1) * v;
        if (rp) ans += query(rp, mid + 1, r, v);
        else ans += 1LL * (r - mid) * v;
        return ans;
    }
} seg;
int root;

int main() {
    //printf("%f\n", sizeof(seg) / 1024.0 / 1024.0);
    int n;
    scanf("%d", &n);
    while (n--) {
        int a, b, k;
        scanf("%d%d%d", &a, &b, &k);
        seg.update(root, 0, ALL, a, b - 1, k);
    }
    printf("%lld\n", seg.query(root, 0, ALL, 0));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Mrzdtz220/p/12305205.html