一、内容
题意:给定【1,8000】区间,给定n组操作,每次将一段区间修改成某种颜色(对上一次颜色进行覆盖),最后问你能看到多少种颜色,且每种颜色有多少段。
二、思路
- 题目给定的区间是**(x, y】左开右闭的区间**
- 进行对区间的修改即可,每次记录下lazy,修改时候pushdown。
- 查询的时候采取单点查询,用last=-1,记录下上一次的颜色从1。。。。8000每个点进行查询如果与上一种颜色不相同,则这种颜色段数++。
三、代码
#include <cstdio>
#include <cstring>
const int maxn = 8005;
int n, color[maxn << 2], vis[maxn], x, y, c, last;
void pushdown(int id) {
if (color[id] == -1) return;
color[id << 1] = color[id << 1 | 1] = color[id];
color[id] = -1;
}
void update(int id, int l, int r, int x, int y, int c) {
if (x <= l && r <= y) {
color[id] = c;
return;
}
pushdown(id);
int mid = (l + r) >> 1;
if (x <= mid) update(id << 1, l, mid, x, y, c);
if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, c);
}
void query(int id, int l, int r) {
if (l == r) {
if (color[id] != -1 && color[id] != last) {
vis[color[id]]++;
}
//-1也要记录 没有颜色
last = color[id];
return;
}
pushdown(id);
int mid = (l + r) >> 1;
query(id << 1, l, mid);
query(id << 1 | 1, mid + 1, r);
}
int main() {
while (scanf("%d", &n) != EOF) {
memset(color, -1, sizeof(color));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &x, &y, &c);
update(1, 1, 8000, x + 1, y, c);
}
query(1, 1, 8000);
last = -1;
for (int i = 0; i <= 8000; i++) {
if (vis[i]) printf("%d %d\n", i, vis[i]);
}
printf("\n");
}
return 0;
}