ZOJ1610 線段樹


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

 

 題意:
0~8000長的線段,有n個染色操作,每次染[a,b]區間(染線段,不是染點),問最后沒有被覆蓋的顏色有多少,他們各有幾個區間段。
代碼:
//類似於貼海報的題,可以把每個染色區間左值+1,變成不連續,這樣就可以看成點了。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=8003;
int val[maxn*4],num[maxn],n,last;
void Pushdown(int rt)
{
    if(val[rt]!=-1)
        val[rt<<1]=val[rt<<1|1]=val[rt];
    val[rt]=-1;
}
void Update(int ql,int qr,int c,int l,int r,int rt)
{
    if(ql<=l&&qr>=r){
        val[rt]=c;
        return;
    }
    Pushdown(rt);
    int m=(l+r)>>1;
    if(ql<=m) Update(ql,qr,c,l,m,rt<<1);
    if(qr>m) Update(ql,qr,c,m+1,r,rt<<1|1);
}
void Query(int l,int r,int rt)
{
    if(l==r){//算顏色段
        if(val[rt]!=-1&&val[rt]!=last)
            num[val[rt]]++;
        last=val[rt];
        return;
    }
    Pushdown(rt);
    int m=(l+r)>>1;
    Query(l,m,rt<<1);
    Query(m+1,r,rt<<1|1);
}
int main()
{
    while(scanf("%d",&n)==1){
        memset(val,-1,sizeof(val));
        memset(num,0,sizeof(num));
        int a,b,c;
        for(int i=0;i<n;i++){
            scanf("%d%d%d",&a,&b,&c);
            if(a<b) Update(a+1,b,c,1,8000,1);//判斷!
        }
        last=-1;
        Query(1,8000,1);
        for(int i=0;i<=8000;i++){
            if(num[i]) printf("%d %d\n",i,num[i]);
        }
        printf("\n");
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM