版权声明: 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;
}