poj 2777 count color

来源:互联网 发布:博易大师软件 编辑:程序博客网 时间:2024/06/05 04:50

线段树区间染色,判断区间颜色的数目

典型的成段更新,懒惰思想

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100010;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int col[maxn<<2];//是否被某种颜色完全覆盖
int sum[maxn<<2];//刚开始想只用一个域来表示,但是怕会分不清楚的,所以,还是分开表示了
int T;
void pushup(int rt){
sum[rt]=sum[rt<<1]|sum[rt<<1|1];
}
void pushdown(int rt){
if(col[rt]){
col[rt<<1]=col[rt<<1|1]=col[rt];
sum[rt<<1]=sum[rt<<1|1]=sum[rt];
col[rt]=0;
}
}
void update(int L,int R,int val,int l,int r,int rt){
if(L<=l&&r<=R){
col[rt]=1;
sum[rt]=1<<(val-1);
return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(L,R,val,lson);
if(R>m) update(L,R,val,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R) return sum[rt];
pushdown(rt);
int m=(l+r)>>1;
int ret1=0,ret2=0;;
if(L<=m) ret1=query(L,R,lson);
if(m<R) ret2=query(L,R,rson);
return ret1|ret2;
}
int calc(int num){
int ans=0;
for(int i=0;i<T;i++)
if(num&(1<<i)) ans++;
return ans;
}
int main(){
int L,op;
int a,b,c;
char s[10];
while(scanf("%d%d%d",&L,&T,&op)!=EOF){
sum[1]=col[1]=1;
while(op--){
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);
update(a,b,c,1,L,1);
}
else {
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
printf("%d\n",calc(query(a,b,1,L,1)));
}
}
}
return 0;
}



原创粉丝点击