当前位置:编程学习 > C/C++ >>

ZOJ 1610 Count the Colors

传说中的区间染色问题

看了好几个区间染色问题,也问了神犇,目测只有暴力的方法啊。。

这道题是因为只询问一次,所以比较好搞,不用维护父节点有多少种颜色。。

先用update pushdown 记录该节点是否被单一颜色覆盖了,如果是记录该颜色(c)

如果不是设置成-1就行了

pushup函数就是看两个子节点是否颜色相同,相同就更新父节点,不同父节点就-1

全部操作完了以后把每一个叶子节点的颜色都推出来,然后算一边就行了。。。

 

这题需要注意的是,染色是不包括端点的,需要把坐标乘以2(l*2,r*2-1),

另外color初始化要X*4 不要X(调了好久才发现= =)

代码:

[cpp] 
#include<stdio.h>  
#define lson l,mid,rt*2  
#define rson mid+1,r,rt*2+1  
#define X 16010  
int color[X*4],ll,rr,c; 
int as[X],f[X]; 
void pushup(int rt){ 
    color[rt]=color[rt*2]==color[rt*2+1]?color[rt*2]:-1; 

void pushdown(int rt){ 
    if(color[rt]>=0){ 
        color[rt*2]=color[rt*2+1]=color[rt]; 
        color[rt]=-1; 
    } 

void update(int l,int r,int rt){ 
    if(ll<=l&&rr>=r){ 
        color[rt]=c; 
        return ; 
    } 
    int mid=l+r>>1; 
    pushdown(rt); 
    if(ll<=mid)update(lson); 
    if(rr> mid)update(rson); 
    pushup(rt); 
     

void solve(int l,int r,int rt){ 
    if(l==r){f[l]=color[rt];return ;} 
    pushdown(rt); 
    int mid=l+r>>1; 
    solve(lson); 
    solve(rson); 

int main(){ 
    int i,j,n; 
    while(~scanf("%d",&n)){ 
        for(i=0;i<X*4;i++)color[i]=-1; 
        for(i=0;i<X;i++){ 
            as[i]=0; 
            f[i]=-1; 
        } 
        for(i=0;i<n;i++){ 
            scanf("%d%d%d",&ll,&rr,&c); 
            ll*=2;rr=rr*2-1; 
            update(0,X,1); 
        } 
        solve(0,X,1); 
        for(i=0;i<X;i++) 
            if(f[i]!=f[i+1]&&f[i]>=0) 
                as[f[i]]++; 
        for(i=0;i<X;i++) 
            if(as[i]) 
                printf("%d %d\n",i,as[i]); 
        puts(""); 
    } 
    return 0; 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,