传送门

有n次操作,每次都是对一根线中的一段区间进行染色(颜色并不相同),有时候后面的颜色有可能覆盖前面的颜色,问最后涂完色,能看到的颜色有几种,每种颜色有几部分?

感觉跟贴海报那个题挺像的,就是这个加了一个计数的部分,所以就用一个sum来计数,最后也判断sum来进行输出

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=8010 * 4;
int tree[maxn],num[maxn],n,last;
void Push(int p)
{
    if(tree[p] != -1)
        tree[p * 2] = tree[p * 2 + 1] = tree[p];
    tree[p] = -1;
}
void Change(int p,int l,int r,int L,int R,int c)
{
    if(L <= l && R >= r)
    {
        tree[p] = c;
        return;
    }
    Push(p);
    int mid = (l + r) / 2;
    if(L <= mid)
        Change(p * 2,l,mid,L,R,c);
    if(R > mid)
        Change(p * 2 + 1,mid + 1,r,L,R,c);
}
void Query(int p,int l,int r)
{
    if(l == r)
    {//算颜色段
        if(tree[p] != -1 && tree[p] != last)
            num[tree[p]]++;
        last = tree[p];
        return;
    }
    Push(p);
    int mid = (l + r) / 2;
    Query(p * 2,l,mid);
    Query(p * 2 + 1,mid + 1,r);
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(tree,-1,sizeof(tree));
        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)//判断!
                Change(1,1,8000,a+1,b,c);
        }
        last = -1;
        Query(1,1,8000);
        for(int i = 0;i <= 8000; i++)
            if(num[i])
                printf("%d %d\n",i,num[i]);
        printf("\n");
    }
    return 0;
}