ZOJ1610 Count the Colors

给出每一线段的颜色,存在颜色覆盖,要求最后能看到的每种颜色及其段数

线段树区间更新~

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=10014;
struct node {
    int l;
    int r;
    int color;
}segTree[maxn*4];
int color[maxn];
int tmp;
void build (int i,int l,int r) {
    segTree[i].l=l;
    segTree[i].r=r;
    segTree[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 update (int i,int l,int r,int c) {
    if (l==r) return;
    if (segTree[i].color==c) return;
    if (l<=segTree[i].l&&r>=segTree[i].r) {
        segTree[i].color=c;
        return;
    }
    if (segTree[i].color>=0) {
        //存在颜色,往下更新
        segTree[i<<1].color=segTree[i].color;
        segTree[i<<1|1].color=segTree[i].color;
        segTree[i].color=-2;//表示有多种颜色 
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if (r<=mid) update(i<<1,l,r,c);
    else if (l>mid) update(i<<1|1,l,r,c);
    else {
        update(i<<1,l,mid,c);
        update(i<<1|1,mid,r,c);
    } 
    segTree[i].color=-2;
}
void cnt (int i) {
    //统计各颜色的段数
    if (segTree[i].color==-1) {
        tmp=-1;
        return;
    } 
    if (segTree[i].color!=-2) {
        if (segTree[i].color!=tmp) {
            //tmp存的是前一段的颜色
            color[segTree[i].color]++;
            tmp=segTree[i].color; 
        }
        return;
    }
    if (segTree[i].l+1!=segTree[i].r) {
        cnt(i<<1);
        cnt(i<<1|1);
    }
}
int main () {
    int n,a,b,c;
    int Max;
    while (~scanf("%d",&n)) {
        build (1,0,8000);
        Max=0;
        while (n--) {
            scanf ("%d %d %d",&a,&b,&c);
            update(1,a,b,c);
            if (c>Max) Max=c;
        }
        tmp=-1;
        memset (color,0,sizeof(color));
        cnt(1);
        for (int i=0;i<=Max;i++) 
        if (color[i]) printf ("%d %d
",i,color[i]);
        printf ("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhanglichen/p/12308483.html