POJ-2777-Count Color(区间染色 统计区间颜色数目)

题目

有一块很长的板子,它的长度是L厘米,L是一个正整数,所以我们可以把板子平均分成L段,它们被标记为1,2,…L从左到右,每个都是1厘米长。现在我们要给木板上色——一段只有一种颜色。我们可以在板上做以下两个操作:
1 “C A B C”将板子从A段涂到B段的颜色为C。
2 “P A B”输出A段和B段(包括)之间绘制的不同颜色的数量。
在我们的日常生活中,我们很少有词语来描述一种颜色(红、绿、蓝、黄……),所以你可能会认为不同颜色T的总数很小。为了简单起见,我们将颜色的名称表示为颜色1、颜色2、…开始时,这块木板被涂成颜色1。剩下的问题就交给你了。

输入

第一行输入包含L (1 <= L <= 100000)、T (1 <= T <= 30)和O (1 <= O <= 100000)。这里O表示操作次数。在O行之后,每一行都包含前面定义的操作“C A B C”或“P A B”(这里的A、B、C是整数,A可能大于B)。

输出

输出结果按输出操作顺序排列,每行包含一个数字。


题解:tag上推。无颜色为0 颜色多种 或者一边有一边没有为-1。
找到一个包含cl,cr的区间而且tag[pos]!=-1,就应该return 了。tag[pos]!=0 ans++;
找到一个cl,cr包含的区间而且tag[pos]!=-1,也应该return 了。tag[pos]!=0 ans++;
pushdown 时 tag[pos]=0||tag[pos]=-1 时return;

#include
#include
#include
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=1e5+5;
int tag[N*3],vis[32],ans;
void pushdown(int pos){
    if(tag[pos]<=0) return;
    tag[pos<<1]=tag[pos<<1|1]=tag[pos];
}
void chanspan(int cl,int cr,int val,int l,int r,int pos){
    if(cl<=l&&r<=cr){tag[pos]=val;return;}
    pushdown(pos);
    int mid=(l+r)>>1;
    if(cl<=mid) chanspan(cl,cr,val,l,mid,pos<<1);
    if(cr>mid) chanspan(cl,cr,val,mid+1,r,pos<<1|1);
    tag[pos]=(tag[pos<<1]==tag[pos<<1|1])?tag[pos<<1]:-1;
}
void query(int cl,int cr,int l,int r,int pos){
    if(tag[pos]>=0&&(l<=cl&&cr<=r||cl<=l&&r<=cr)){//直接if(tag[pos]>=0)即可
        if(tag[pos]&&!vis[tag[pos]]) ++ans,vis[tag[pos]]=1;
        return;
    }
    pushdown(pos);
    int mid=(l+r)>>1;
    if(cl<=mid) query(cl,cr,l,mid,pos<<1);
    if(cr>mid) query(cl,cr,mid+1,r,pos<<1|1);
}
int main(){
    int n,color,q;char str[3];
    while(~scanf("%d%d%d",&n,&color,&q)){
        tag[1]=1;
        while(q--){
            scanf("%s",str);int cl,cr,val,t;
            if(str[0]=='C'){
                scanf("%d%d%d",&cl,&cr,&val);
                if(cl>cr) swap(cl,cr);
                chanspan(cl,cr,val,1,n,1);
            }
            else{
                scanf("%d%d",&cl,&cr);
                if(cl>cr) swap(cl,cr);
                query(cl,cr,1,n,1);
                printf("%d\n",ans),ans=0;
                m(vis,0);
            }
        }
    }
}

你可能感兴趣的:(数据结构==线段树)