ZOJ - 1610 区间修改+暴力单点查询

一、内容

题意:给定【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;
}
发布了357 篇原创文章 · 获赞 287 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41280600/article/details/101058854