Count the Colors-ZOJ1610(线段树区间求)

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

题目大意:

在一条线上花颜色,求出最后看到的颜色种类

分析:

因为从0开始,所以应该用区间

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
#define N 8005
#define Lson r<<1
#define Rson r<<1|1
int sum[N],temp;

struct node
{
    int L,R,e;
    int mid()
    {
        return (L+R)/2;
    }
    int len()
    {
        return R-L+1;
    }
}a[N*4];

void BuildTree(int r,int L,int R)
{
    a[r].L=L;
    a[r].R=R;
    a[r].e=-1;
    if(L==R-1)
    {
        return;
    }
    BuildTree(Lson,L,a[r].mid());
    BuildTree(Rson,a[r].mid(),R);
}
void Qurry(int r)
{
    if(a[r].e!=-1)
    {
        if(a[r].e!=temp)
        {//temp表示这个区间的颜色没有被加过
            sum[a[r].e]++;
        }
        temp=a[r].e;
        return;
    }
    if(a[r].L==a[r].R-1)
    {
        temp=-1;
        return;
    }
        Qurry(Lson);
        Qurry(Rson);
}
void Update(int r,int L,int R,int e)
{

    if(a[r].L==L && a[r].R==R)
    {
        a[r].e=e;
        return;
    }
    if(a[r].e!=-1)
    {
        a[Lson].e=a[Rson].e=a[r].e;
        a[r].e=-1;
    }
    if(R<=a[r].mid())
        Update(Lson,L,R,e);
    else if(L>=a[r].mid())
        Update(Rson,L,R,e);
    else
    {
        Update(Lson,L,a[r].mid(),e);
        Update(Rson,a[r].mid(),R,e);
    }
}
int main()
{
    int n,x,y,e;
    while(scanf("%d",&n)!=EOF)
    {
        memset(sum,0,sizeof(sum));
        BuildTree(1,0,N);
        int Max=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d %d %d",&x,&y,&e);
            Max=max(Max,e);
            Update(1,x,y,e);

        }
        temp=-1;
        Qurry(1);
        for(int i=0;i<=Max;i++)
        {
            if(sum[i])
            {
                printf("%d %d\n",i,sum[i]);
            }
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-07 07:30:36

Count the Colors-ZOJ1610(线段树区间求)的相关文章

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

非结构体线段树版 ZJU 1610 Count the Colors (线段树区间更新)

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

ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)

1.给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数. 2.线段树区间更新,单点查询. 但是有点细节,比如: 输入: 2 0 1 1 2 3 1 输出: 1 2 这种情况就需要处理一下,代码中把所有的左端点都+1,避免了这种情况. 3. #include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define L(root) ((root) &l

ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】

Count the Colors Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 1610 Description Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent o

Zoj 1610 Count the Colors (线段树+区间更新+暴力计数)

题目大意: 有n次操作,每次都是对一根线中的一段区间进行染色(颜色并不相同),有时候后面的颜色有可能覆盖前面的颜色,问最后涂完色,能看到的颜色有几种,每种颜色有几部分? 解题思路: 这个题目建树的时候有些不同,并不是以点为对象,而是以区间为对象,很明显是对线段树的区间进行操作,更新的时候要以区间为单位,还有就是计算每个区间出现几次的时候可以根据线段树的建树特征对树进行遍历求解. 1 #include <cstdio> 2 #include <cstring> 3 #include

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

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

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

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

hdu4521-小明系列问题——小明序列(线段树区间求最值)

题意:求最长上升序列的长度(LIS),但是要求相邻的两个数距离至少为d,数据范围较大,普通dp肯定TLE.线段树搞之就可以了,或者优化后的nlogn的dp. 代码为  线段树解法. 1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cct

poj3264(线段树区间求最值)

题目连接:http://poj.org/problem?id=3264 题意:给定Q(1<=Q<=200000)个数A1,A2,```,AQ,多次求任一区间Ai-Aj中最大数和最小数的差. 线段树功能:区间求最值,O(logN)复杂度查询 #pragma comment(linker,"/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <stri

HDU - 1754 I Hate It (线段树区间求最值)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:线段树的单点更新和区间求最值 模板题,,,???,, 1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 5 typedef long long LL; 6 const int N=200010; 7 8 LL ans; 9 LL max(LL a,LL b){ 10 if(a>b) r