pku2777 Count Color

思路:用位图记录区间已涂上的颜色

 

#include <iostream>
using namespace std;

#define clr(x) memset(x,0,sizeof(x))
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define MAXN 100002

struct Node{
    
int l,r;
    __int64 s;
}nod[MAXN
*3];


inline 
bool single(__int64 a){
    
return (((a-2& a)==0);
}


void init(int tag,int l,int r){
    nod[tag].l
=l;
    nod[tag].r
=r;
    nod[tag].s
=2;
    
if(l==r){
        
return;
    }
    init(tag
*2,l,(l+r)/2);
    init(tag
*2+1,(l+r)/2+1,r);
}


void query(int tag,int l,int r,__int64 &ss){
    
if(l<=nod[tag].l && nod[tag].r<=r){
        ss
|=nod[tag].s;
        
return;
    }
    
if(single(nod[tag].s)){//若该结点所示区间为单色,则其儿子所示区间也为单色,故无需再查看以该结点为根的树
        ss|=nod[tag].s;
        
return;
    }
    
if(l<=nod[tag*2].r)
        query(tag
*2,l,r,ss);
    
if(r>=nod[tag*2+1].l)
        query(tag
*2+1,l,r,ss);
}


void paint(int tag,int l,int r,int c){//将[l,r]涂成颜色c
    if(l<=nod[tag].l && nod[tag].r<=r){
        nod[tag].s
=(1<<c);
        
return;
    }
    
if(nod[tag].s==(1<<c))//若该区间已被染成颜色c则无需再染
        return;
    
if(single(nod[tag].s)){//若该区间为单色,则在上一次改变中,其儿子没有被改变,又因为需要进入该区间的子树,所以必须先将儿子更新为单色
        nod[tag*2].s=nod[tag].s;
        nod[tag
*2+1].s=nod[tag].s;
    }
    
if(l<=nod[tag*2].r)
        paint(tag
*2,l,r,c);
    
if(r>=nod[tag*2+1].l)
        paint(tag
*2+1,l,r,c);
    nod[tag].s
=nod[tag*2].s|nod[tag*2+1].s;
}



int main(){
    
int L,T,O,i,j,x,y,z,cnt;
    
char ch[3];
    __int64 ss;
    
while(scanf("%d%d%d",&L,&T,&O)!=EOF){
        init(
1,1,L);
        
for(i=0;i<O;i++){
            scanf(
"%s",ch);
            
if(ch[0]=='C'){
                scanf(
"%d%d%d",&x,&y,&z);
                
if(x>y){
                    
int t=x;
                    x
=y;
                    y
=t;
                }
                paint(
1,x,y,z);
            }
            
else{
                scanf(
"%d%d",&x,&y);
                
if(x>y){
                    
int t=x;
                    x
=y;
                    y
=t;
                }
                ss
=0;
                query(
1,x,y,ss);
                cnt
=0;
                
for(j=1;j<=T;j++){
                    
if(ss&(1<<j))
                        cnt
++;
                }
                printf(
"%d\n",cnt);
            }
        }
    }
    
return 0;
}
posted @ 2008-10-16 01:40  Beetlebum  阅读(332)  评论(0编辑  收藏  举报