1. 程式人生 > >F - Count the Colors (覆蓋後還存在的原色的數目)

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

題意:在一條長度為8000的線段上染色,每次把區間[a,b]染成c顏色。顯然,後面染上去的顏色會覆蓋掉之前的顏色。求染完之後,每種顏色線上段上有多少個間斷的區間。線段樹Lazy區間修改。

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=8000+10;
int n,col[maxn<<2],vis[maxn<<2],ans[maxn<<2];
void pushdown(int rt,int m)
{
    if(col[rt]!=-1)
    {
        col[rt<<1]=col[rt<<1|1]=col[rt];
        col[rt]=-1;

    }
}
void updata(int a,int b,int c,int l,int r,int rt)
{
    if(a<=l&&b>=r)
    {
        col[rt]=c;
        return;

    }
    if(col[rt]==c)return;
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    if(a<=m)updata(a,b,c,lson);
    if(b>m)
        updata(a,b,c,rson);

}
void query(int l,int r,int rt)
{
    if(col[rt]!=-1)
    {
        for(int i=l; i<=r; i++)
            vis[i]=col[rt];//每個葉子節點的顏色
        return;

    }
    if(l==r)return;
    int m=(l+r)>>1;
    query(lson);
    query(rson);


}
int main()
{
    int x1,x2,c;
    while(scanf("%d",&n)!=EOF)
    {
        memset(col,-1,sizeof(col));
        memset(vis,-1,sizeof(vis));
        memset(ans,0,sizeof(ans));
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d",&x1,&x2,&c);
            updata(x1+1,x2,c,1,8001,1);
//因為給的是緊密區間,而建的樹點的,所以把左邊的+1,變成點覆蓋的
        }
        query(1,8001,1);
        int i=1;
        while(i<maxn)
        {
            int color,j;
            color=vis[i];
            j=i+1;
            if(color==-1)
            {
                i++;//沒顏色
                continue;
            }
            while(vis[j]!=-1&&vis[j]==color&&j<maxn)
                j++;//連續顏色相同
            ans[color]++;
            i=j;

        }
        for(int i=0; i<maxn; i++)
            if(ans[i])
                printf("%d %d\n",i,ans[i]);
printf("\n");
    }
    return 0;
}