F - Count the Colors ZOJ 1610 (线段树+结点为长度为一的区间+树的遍历)

F - 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 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

题意是区间涂色,最后问你能看见的有颜色,以及他们的段数,

真的是一道很不错的题,  这里最小的是长度为一的区间,而不是一个点,还有再次用到延迟标记,

统计段数就是对树的遍历,同时tmp记录下当前节点的先驱结点的颜色,用于判断,颜色的段数,

//#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=8011;
const int inf=999999999;
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M,R
#define M ((L+R)>>1)
#define For(i,n) for(int i=0;i<(n);i++)
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32);
    bool ok=false;
    if(c=='-')ok=true,c=getchar();
    for(x=0; c>32; c=getchar())
        x=x*10+c-'0';
    if(ok)x=-x;
    return x;
}
template<class T> inline void read_(T&x,T&y)
{
    read(x);
    read(y);
}
template<class T> inline void read__(T&x,T&y,T&z)
{
    read(x);
    read(y);
    read(z);
}
template<class T> inline void write(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    putchar('\n');
}
//-------IO template------
typedef long long  LL;

struct node
{
    int color;//-1 表示区间没有涂色, -2表示区间涂的是混合色
} p[maxn<<3];

void build(int rt,int L,int R)
{
    p[rt].color=-1;
    if(R-L==1)return ;
    build(lson);
    build(rson);
}

int cnt[maxn];
void update(int rt,int L,int R,int x,int y,int color)
{
    if(L==R||p[rt].color==color)return ;
    if(L==x&&y==R)
    {
        p[rt].color=color;
        return ;
    }
    if(p[rt].color>=0)
    {
        p[rt<<1].color=p[rt<<1|1].color=p[rt].color;
        p[rt].color=-2;
    }
    if(L<=x&&y<=M)
        update(lson,x,y,color);
    else if(x>=M&&y<=R)
        update(rson,x,y,color);
    else
    {
        update(lson,x,M,color);
        update(rson,M,y,color);
    }
    p[rt].color=-2;
}

void solve(int rt,int L,int R,int& tmp)
{
    if(p[rt].color==-1)
    {
        tmp=-1;
        return ;
    }
    if(p[rt].color>=0)
    {
        if(tmp!=p[rt].color)
        {
            tmp=p[rt].color;
            cnt[p[rt].color]++;
        }
        return ;
    }
    if(L+1!=R)
    {
        solve(lson,tmp);
        solve(rson,tmp);
    }
}
int main()
{
    int n;
    // freopen("in.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        build(1,0,8000);
        int M1=0;
        For(i,n)
        {
            int left,right,color;
            read__(left,right,color);
            update(1,0,8000,left,right,color);
            M1=max(M1,color);
        }
        memset(cnt,0,sizeof(cnt));
        int tmp=-1;
        solve(1,0,8000,tmp);
        for(int i=0; i<=M1; i++)if(cnt[i])
                printf("%d %d\n",i,cnt[i]);
        printf("\n");

    }
    return 0;
}

时间: 2025-01-04 18:13:12

F - Count the Colors ZOJ 1610 (线段树+结点为长度为一的区间+树的遍历)的相关文章

F - Count the Colors - zoj 1610(区间覆盖)

有一块很长的画布,现在想在这块画布上画一些颜色,不过后面画的颜色会把前面画的颜色覆盖掉,现在想知道画完后这块画布的颜色分布,比如 1号颜色有几块,2号颜色有几块.... *********************************************************************** 分析:基本上跟帖海报是一样的,不过最后要求输出的是这种颜色的画有几块,可以按照贴海报的方式先做出来,然后对每个点进行查询,不晓得复杂度会不会太高.不过还是先试一下吧. 注意:如果出现 S

Count the Colors ZOJ - 1610

GO 题意:给一个区间,有n次染色操作,每次将[x1, x2]染为c,求最后每种颜色各有多少线段可以看到. #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<set> #include<vec

F - Count the Colors

F - Count the Colors ZOJ - 1610 思路:调了一个小时,但是发现自己线段树木有写错,颜色统计出了错误.但是不明白自己颜色统计为什么错了. 求大佬指点迷津.思路很简单,就是一个裸的线段树.只要推出样例就做出来了. 以下是两种颜色统计: 这是我的错误的: for(int i=1;i<=8009;i++){ if(vis[i]!=vis[i-1]&&vis[i-1]!=-1) ans[vis[i-1]]++; if(i==8000&&vis[i]

ZOJ 1610 Count the Colors【题意+线段树区间更新&amp;&amp;单点查询】

任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 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

Count the Colors (zoj 1610 线段树 区间颜色覆盖)

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 线段树区间染色

给长度8000米的板,对其中区间染色,问最后能看到的颜色,和该颜色一共出现了几段 线段覆盖法 数据比较水   也可以暴力水过 线段树: #include "stdio.h" #include "string.h" struct node { int l,r,c; }data[40010]; int color[8011]; void build(int l,int r,int k) { int mid; data[k].l=l; data[k].r=r; data[

zoj 1610 线段树

用线段树进行区间赋值,最后将每个小segment的颜色求出来,再扫一遍判断连续的段数即可. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 8001; 7 int color[N]; 8 int ans[N]; 9 10 struct Node 11 { 12 int l, r, c; 13 } node[N &

(模拟) zoj 1610

F - 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

区间树和线段树

注意:区间树和线段树不一样哦,线段树是一种特殊的区间树. 区间树: 区间树是在红黑树基础上进行扩展得到的支持以区间为元素的动态集合的操作,其中每个节点的关键值是区间的左端点.通过建立这种特定的结构,可是使区间的元素的查找和插入都可以在O(lgn)的时间内完成.相比于基础的红黑树数据结构,增加了一个max[x],即以x为根的子树中所有区间的断点的最大值.逻辑结构如下所示: 区间树具有和红黑树一样的性质,并且区间树的基础操作和红黑树的基础操作一样.(具体红黑树的操作,参见http://blog.cs