HDU - 6183 Color it

版权声明: https://blog.csdn.net/moon_sky1999/article/details/87973917

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=6183

思路来自:https://blog.csdn.net/jinglinxiao/article/details/77822234

对于每次查询,可以依次枚举所有颜色,查看该种颜色是否在所查询的矩形内,统计所有出现的颜色的个数。

考虑到每次查询的矩形都是贴着y轴的,这样只需要知道y轴该区间内是否有点的x值小于矩形右端点。

对y轴建一颗线段树,用来维护x的最低值。

若每一种颜色都建一棵树,那么空间开销过大。需要动态开点。

而且二维的可能开不下,需要将所有的颜色压到一个一维数组里。

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn = (1e6 + 10) * 51;
const int inf = 1e9 + 10;

int ls[maxn], rs[maxn], cnt;

struct tree {
    int left, right, mmin;
} c[maxn];

void build(int id, int l, int r) {
    c[id].left = l;
    c[id].right = r;
    c[id].mmin = inf;
    ls[id] = rs[id] = 0;
}

void update(int id, int pos, int v) {
    if (c[id].left == c[id].right)c[id].mmin = min(c[id].mmin, v);
    else {
        int mid = (c[id].left + c[id].right) >> 1;
        if (pos <= mid) {
            if (ls[id] == 0) {
                ls[id] = cnt;
                build(cnt, c[id].left, mid);
                ++cnt;
            }
            update(ls[id], pos, v);
            c[id].mmin = min(c[id].mmin, c[ls[id]].mmin);
        } else {
            if (rs[id] == 0) {
                rs[id] = cnt;
                build(cnt, mid + 1, c[id].right);
                ++cnt;
            }
            update(rs[id], pos, v);
            c[id].mmin = min(c[id].mmin, c[rs[id]].mmin);
        }
    }
}

bool query_min(int id, int l, int r, int ck) {
    if (c[id].left == l && c[id].right == r)return (ck >= c[id].mmin);
    if (c[id].mmin > ck)return 0;
    int mid = (c[id].left + c[id].right) >> 1;
    if (r <= mid) {
        if (ls[id] != 0)return query_min(ls[id], l, r, ck);
    } else if (l > mid) {
        if (rs[id] != 0)return query_min(rs[id], l, r, ck);
    } else {
        if (ls[id] != 0 && query_min(ls[id], l, mid, ck))return 1;
        else if (rs[id] != 0 && query_min(rs[id], mid + 1, r, ck))return 1;
    }
    return 0;
}

void work0() {
    cnt = 0;
    for (int i = 0; i <= 50; ++i) {
        build(i, 1, 1000000);
        cnt++;
    }
}

void work1() {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    update(c, y, x);
}

void work2() {
    int x, y1, y2;
    scanf("%d%d%d", &x, &y1, &y2);
    int tot = 0;
    for (int i = 0; i <= 50; ++i) {
        if (query_min(i, y1, y2, x))
            ++tot;
    }
    printf("%d\n", tot);
}

int main() {
    int cp;
    work0();
    while (~scanf("%d", &cp)) {
        if (cp == 0)work0();
        else if (cp == 1)work1();
        else if (cp == 2)work2();
        else break;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/87973917