ZOJ1610(Count the Colors)

Count the Colors
Time Limit: 1 Second      Memory Limit: 32768 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

 

//1830829    2009-04-12 12:32:15    Accepted     1610    C++    60    496    Xredman
#include <iostream>
#include 
<queue>
#include 
<map>
using namespace std;

const int N = 8004;

///////////////////////////////

typedef 
struct
{
    
int left, right;
    
int color;
}
LineTNode;

/////////////////////////////////
LineTNode LineTree[N * 2], LineCount[N];
int cnt[N];
int n;
map
<intint> ans;
map
<intint>::iterator p;

void createLTree(int low, int high)
{
    
int kk = 1, mid, tkk;
        ;
    LineTree[kk].left 
= low;
    LineTree[kk].right 
= high;
    LineTree[kk].color 
= -1;

    queue
<int> Q;
    Q.push(kk);

    
while(!Q.empty())
    
{
        kk 
= Q.front();
        Q.pop();
        low 
= LineTree[kk].left;
        high 
= LineTree[kk].right;
        
if(low + 1 == high || low >= high)
            
continue;
        mid 
= (low + high) / 2;
        
//////////////左孩子//////////////////
        tkk = kk * 2;

        LineTree[tkk].left 
= low;
        LineTree[tkk].right 
= mid;
        LineTree[tkk].color 
= -1;
        Q.push(tkk);

        
///////////////右孩子/////////////////////
        tkk ++;
        LineTree[tkk].left 
= mid;
        LineTree[tkk].right 
= high;
        LineTree[tkk].color 
= -1;
        Q.push(tkk);
    }

}


void insert(int low, int high, int step, int color)
{
    
int mid;
    
int left, right;
    
////////////////此时找到匹配线段段/////////////////////////

    
if(low == LineTree[step].left && high == LineTree[step].right)
    
{
        LineTree[step].color 
= color;
        
return ;
    }


    
/////////////////////////////////////////////////////////

    
////////////此时情况为查至元线段仍未找到匹配线段//////////

    if(LineTree[step].left + 1 == LineTree[step].right)
        
return ;//搜至元线段,插入结束

    
/////////////////////////////////////////////////////////

    mid 
= (LineTree[step].left + LineTree[step].right) / 2;

    left 
= step * 2;//左枝
    right = step * 2 + 1;//右枝

    
//=============若初段为非混合色,则极有可能将被覆盖掉一半 or 全部======

    
if(LineTree[step].color != -2)
    
{//非混合色
        LineTree[left].color = LineTree[step].color;
        LineTree[right].color 
= LineTree[step].color;
    }


    
if(mid >= high)//插入左枝
        insert(low, high, left, color);
    
else if(mid < low)//插入右枝
        insert(low, high, right, color);
    
else
    
{//左右枝均需插入
        insert(low, mid, left, color);
        insert(mid, high, right, color);
        
    }


    
/////////////////////////对当前线段继续处理,或为混合色,或为单色///////////////

    
if(LineTree[left].color >= 0 && LineTree[left].color == LineTree[right].color)
    
{
        LineTree[step].color 
= LineTree[left].color;
    }

    
else
    
{
        LineTree[step].color 
= -2;
    }

}


void Calc(int step)
{
    
if(LineTree[step].color == -1)
    
{//未着色
        return ;
    }

    
if(LineTree[step].color == -2)
    
{//混合色
        Calc(step * 2);
        Calc(step 
* 2 + 1);
    }

    
else
    
{
        
//对单色情况做处理,这也是关键部分
        for(int i = LineTree[step].left; i < LineTree[step].right; i++)
            cnt[i] 
= LineTree[step].color;
    }

}


int main()
{
    
int minc, maxc, i, cc;
    
while(cin>>n)
    
{
        minc 
= N; maxc = -1;
        
for(i = 0; i < n; i++)
        
{
            scanf(
"%d%d%d",&LineCount[i].left, &LineCount[i].right, &LineCount[i].color);
            
if(LineCount[i].left < minc) minc = LineCount[i].left;
            
if(LineCount[i].right > maxc) maxc = LineCount[i].right;
        }

        createLTree(minc, maxc);
        
for(i = 0; i < n; i++)
            insert(LineCount[i].left, LineCount[i].right, 
1, LineCount[i].color);
        ans.clear();
        
for(i = minc ; i <= maxc; i++)
            cnt[i] 
= -1;

        Calc(
1);
        cc 
= -1;
        
for(i = minc ; i <= maxc; i++)
            
if(cnt[i] != -1)
            
{
                
if(cnt[i] != cc)
                
{
                    cc 
= cnt[i];
                    ans[cc]
++;
                }

            }

            
else cc = -1;
            

        p 
= ans.begin();
        
while(p != ans.end())
        
{
            cout
<<p->first<<" "<<p->second<<endl;
            p
++;
        }

        cout
<<endl;
    }

    
return 0;
}

 

posted on 2009-04-12 12:48  Xredman  阅读(1097)  评论(0编辑  收藏  举报

导航