ZOJ1610——Count the Colors

Count the Colors


Time Limit: 2 Seconds     
Memory Limit: 65536 KB


Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.

Your task is counting the segments of different colors you can see at last.

Input

The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.

Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:

x1 x2 c

x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.

All the numbers are in the range [0, 8000], and they are all integers.

Input may contain several data set, process to the end of file.

Output

Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.

If some color can‘t be seen, you shouldn‘t print it.

Print a blank line after every dataset.

Sample Input

5

0 4 4

0 3 1

3 4 2

0 2 2

0 2 3

4

0 1 1

3 4 1

1 3 2

1 3 1

6

0 1 0

1 2 1

2 3 1

1 2 0

2 3 0

1 2 1

Sample Output

1 1

2 1

3 1

1 1

0 2

1 1

Count the Colors


Time Limit: 2 Seconds     
Memory Limit: 65536 KB


Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.

Your task is counting the segments of different colors you can see at last.

Input

The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.

Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:

x1 x2 c

x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.

All the numbers are in the range [0, 8000], and they are all integers.

Input may contain several data set, process to the end of file.

Output

Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.

If some color can‘t be seen, you shouldn‘t print it.

Print a blank line after every dataset.

Sample Input

5

0 4 4

0 3 1

3 4 2

0 2 2

0 2 3

4

0 1 1

3 4 1

1 3 2

1 3 1

6

0 1 0

1 2 1

2 3 1

1 2 0

2 3 0

1 2 1

Sample Output

1 1

2 1

3 1

1 1

0 2

1 1

水题线段树

#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 8010;

int cnt[N], ret;
struct node
{
	int l, r;
	int col;
}tree[N << 2], seg[N], rec[N];

void build (int p, int l, int r)
{
	tree[p].l = l;
	tree[p].r = r;
	tree[p].col = -1;
	if (l == r)
	{
		return;
	}
	int mid = (l + r) >> 1;
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);
}

void update(int p, int l, int r, int col)
{
	if (tree[p].l >= l && r >= tree[p].r)
	{
		tree[p].col = col;
		return;
	}
	if (tree[p].col != -1)
	{
		tree[p << 1].col = tree[p].col;
		tree[p << 1 | 1].col = tree[p].col;
		tree[p].col = -1;
	}
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (r <= mid)
	{
		update(p << 1, l, r, col);
	}
	else if (l > mid)
	{
		update(p << 1 | 1, l, r, col);
	}
	else
	{
		update(p << 1, l, mid, col);
		update(p << 1 | 1, mid + 1, r, col);
	}
}

void query (int p)
{
	if (tree[p].col != -1)
	{
		rec[ret].l = tree[p].l;
		rec[ret].r = tree[p].r;
		rec[ret++].col = tree[p].col;
		return;
	}
	query(p << 1);
	query(p << 1 | 1);
}

int main()
{
	int n, l, r;
	while(~scanf("%d", &n))
	{
		l = 10000, r = -10000;
		memset (cnt, 0, sizeof(cnt));
		for (int i = 0; i < n; ++i)
		{
			scanf("%d%d%d", &seg[i].l, &seg[i].r, &seg[i].col);
			l = min(l, seg[i].l);
			r = max(r, seg[i].r);
		}
		build(1, l + 1, r);
		ret = 0;
		for (int i = 0; i < n; ++i)
		{
			update(1, seg[i].l + 1, seg[i].r, seg[i].col);
		}
		query(1);
		cnt[rec[0].col]++;
		for (int i = 1; i < ret; ++i)
		{
			if (rec[i].col != rec[i - 1].col)
			{
				cnt[rec[i].col]++;
			}
			else if (rec[i].l > rec[i - 1].r + 1)
			{
				cnt[rec[i].col]++;
			}
		}
		for (int i = 0; i <= 8000; ++i)
		{
			if (cnt[i] != 0)
			{
				printf("%d %d\n", i, cnt[i]);
			}
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-10-05 05:06:03

ZOJ1610——Count the Colors的相关文章

ZOJ1610 Count the Colors 经典线段树染色问题

题意,给你n个  x,y,c,意思就是区间[x,y]被染成C色,但是颜色会被覆盖的,染色操作完成以后 问你每种颜色有多少段 并输出颜色编号id跟段数cnt 经典问题,不过写的有点撮吧,没去看别人的,这个方法应该是最传统的最普通的,常规的开数组记录,也许大神们有更高端的方法 #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring>

ZOJ-1610 Count the Colors ( 线段树 )

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Description Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different

线段树专题—ZOJ1610 Count the Colors

题意:给一个n,代表n次操作,接下来每次操作表示把[l,r]区间的线段涂成k的颜色其中,l,r,k的范围都是0到8000 分析:其实就是拿线段树维护一段区间的颜色,总体用到的是线段树的区间更新把,但是会给人一种区间合并的错觉 注意:这题比较坑的是千万不能拿n建树,不然就会segmentation fault,必须拿8000建树,也就是树是固定的 代码: #include<cstdio> #include<cstring> #include<algorithm> #inc

ZOJ1610 Count the Colors 线段树

正常区间修改,然后最后一起暴力查一遍就行了. 区间修改有0,需要用-1做lzy标记.... 1 #include <cstdio> 2 #include <map> 3 #include <algorithm> 4 using namespace std; 5 int col[40000],lzy[40000],vec[10000],cnt[10000]; 6 int n; 7 void build(int k,int l,int r) 8 { 9 col[k] = -

zoj 1610 Count the Colors

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610 先用线段树维护区间颜色的覆盖,然后在把区间的颜色映射到数组,再从数组统计颜色. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 100000 5 using namespace std; 6 7 int n; 8 int min1; 9

zoj 1610 Count the Colors 【区间覆盖 求染色段】

Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can s

Count the Colors

B - Count the Colors Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task

ZOJ 1610 Count the Colors(线段树lazy+暴力统计)

Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can s

ZOJ 1610 Count the Colors (线段树区间更新)

题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头输出. //ZOJ 1610 #include <cstdio> #include <cstring> #include <iostream> using namespace std ; int p[8010*4],lz[8010*4] ,hashh[8010*4],has