HDU - 6183 动态开点线段树

HDU - 6183 动态开点线段树+维护最值


题目链接
考虑对每种颜色都沿y轴建立线段树,维护区间点的x坐标的最小值。
线段树需要动态开点不然会mle

#include <algorithm>
#include <cstdio>
#include <cstring>
const int N = 1000005*51;
const int INF = 0x3f3f3f3f;
int c[N], ls[N], rs[N], tot;
int rt[51];
int newNode() {
    c[++tot] = INF;
    ls[tot] = rs[tot] = 0;
    return tot;
}
void update(int &k, int l, int r, int y, int val) {
    if (!k) k = newNode();
    c[k] = std::min(c[k], val);
    if (l == r) return;
    int mid = (l + r) >> 1;
    if (mid >= y)
        update(ls[k], l, mid, y, val);
    else
        update(rs[k], mid + 1, r, y, val);
}
int query(int k, int l, int r, int left, int right) {
    if (!k) return INF;
    if (left <= l && r <= right)
        return c[k];
    int mid = (l + r) >> 1;
    if (right <= mid)
        return query(ls[k], l, mid, left, right);
    else if (left > mid)
        return query(rs[k], mid + 1, r, left, right);
    else
        return std::min(query(ls[k], l, mid, left, right), query(rs[k], mid + 1, r, left, right));
}
int main() {
    // freopen("out.txt", "w", stdout);
    int op, x, y, c, yy;
    while (true) {
        scanf("%d", &op);
        if (op == 3) break;
        if (op == 0) {
            tot = 0;
            for (int i = 0; i < 51; ++i) rt[i] = newNode();
        } else if (op == 1) {
            scanf("%d%d%d", &x, &y, &c);
            update(rt[c], 1, 1000000, y, x);
        } else {
            scanf("%d%d%d", &x, &y, &yy);
            int ans = 0;
            for (int i = 0; i < 51; ++i) {
                if (x >= query(rt[i], 1, 1000000, y, yy)) ans++;
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43135318/article/details/87970826