zoj 1610 Count the Colors[线段树]

来源:互联网 发布:行知中学地址 编辑:程序博客网 时间:2024/05/07 21:18
#include<cstring>//给了每一线段的颜色,存在颜色覆盖,求表面上看能看到的颜色种类和各种颜色的段数#include<cstdio>using namespace std;#define lson    l,m,rt<<1#define rson    m,r,rt<<1|1struct node{int l,r,col;};const int maxn=8008;node no[maxn<<2];int col[maxn<<2];//  记录颜色种类.int res[maxn<<2];// 记录颜色的段数.void init(){    //初始化...    memset(no,0,sizeof(no));    memset(col,-1,sizeof(col));}void pushdown(int rt){  //更新子结点.    if(no[rt].col>=0){        no[rt<<1].col=no[rt<<1|1].col=no[rt].col;        no[rt].col=-1;     //不要更新到底    }}void build(int l,int r,int rt){ //建树    no[rt].l=l;    no[rt].r=r;    no[rt].col=-1;    if(l==r-1)    return;    int m=(l+r)>>1;    build(lson);    build(rson);}void update(int p,int l,int r,int rt){ //涂色.更新    if(no[rt].l>=l&&r>=no[rt].r) {        //颜色范围要比x1,x2小才能涂色.        no[rt].col=p;        return ;    }    if(no[rt].col==p) return;//颜色相同    pushdown(rt);   //更新子节点    int m=(no[rt].l+no[rt].r)>>1;    if(l>=m)        update(p,l,r,rt<<1|1);    else if(r<=m)        update(p,l,r,rt<<1);    else {        update(p,lson);        update(p,rson);    }}void query(int l,int r,int rt){ //更新,计算col的值.    if(no[rt].col>=0){        for(int i=l;i<r;i++)            col[i]=no[rt].col;        return ;    }    if(no[rt].l==no[rt].r-1) return ;    int m=(no[rt].l+no[rt].r)>>1;    if(l>=m)    query(l,r,rt<<1|1);    else if(r<=m)   query(l,r,rt<<1);    else {        query(lson);        query(rson);    }}int main(){    int n,x1,x2,c;    while(~scanf("%d",&n)){        init();        build(0,maxn,1);        while(n--){            scanf("%d%d%d",&x1,&x2,&c);            update(c,x1,x2,1);        }        query(0,maxn,1);//计算memset(res,0,sizeof(res));for(int i=0;i<maxn;i++){if(col[i+1]!=col[i]&&col[i]!=-1){res[col[i]]++;}}        for(int i=0;i<maxn;i++) {            if(res[i]) printf("%d %d\n",i,res[i]);        }        printf("\n");    }    return 0;}

原创粉丝点击