Count the Colors ZOJ - 1610 区间颜色覆盖

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=8010;
struct Node
{
    int l,r;
    int color;
}tr[MAXN*3];
int color[MAXN];
int temp;
void build(int i,int l,int r)
{
    tr[i].l=l;
    tr[i].r=r;
    //-1表示没有颜色
    tr[i].color=-1;
    if(l+1==r)
        return;
    int mid=((l+r)>>1);
    build(i<<1,l,mid);
    build((i<<1)|1,mid,r);
}
void insert(int i,int l,int r,int c)
{
    if(l==r)
        return;
    if(tr[i].color==c)
        return;
    if(l<=tr[i].l&&r>=tr[i].r)
    {
        tr[i].color=c;
        return;
    }
    //存在颜色,往下更新
    if(tr[i].color>=0)
    {
        tr[i<<1].color=tr[i].color;
        tr[(i<<1)|1].color=tr[i].color;
        //表示有多种颜色
        tr[i].color=-2;
    }
    int mid=((tr[i].l+tr[i].r)>>1);
    if(r<=mid) 
        insert(i<<1,l,r,c);
    else if(l>=mid) 
        insert((i<<1)|1,l,r,c);
    else
    {
        insert(i<<1,l,mid,c);
        insert((i<<1)|1,mid,r,c);
    }
    tr[i].color=-2;
}
//统计各颜色的段数
void query(int i)
{
    if(tr[i].color==-1)
    {
        temp=-1;
        return;
    }
    if(tr[i].color!=-2)
    {
        //temp存的是前一段的颜色
        if(tr[i].color!=temp)
        {
            color[tr[i].color]++;
            temp=tr[i].color;
        }
        return;
    }
    if(tr[i].l+1!=tr[i].r)
    {
        query(i<<1);
        query((i<<1)|1);
    }
}
int main()
{
    int n,a,b,c;
    int Max;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,0,8000);
        Max=0;
        while(n--)
        {
            scanf("%d%d%d",&a,&b,&c);
            insert(1,a,b,c);
            if(c>Max)
                Max=c;
        }
        temp=-1;
        memset(color,0,sizeof(color));
        query(1);
        for(int i=0;i<=Max;i++)
            if(color[i])
                printf("%d %d\n",i,color[i]);
        printf("\n");
    }
    return 0;
}

 

posted @ 2020-02-11 09:43  晴屿  阅读(114)  评论(0编辑  收藏  举报