POJ 2777 Count Color

区间染色第二题

这次询问次数很多,但是颜色很少,用位运算维护父子节点颜色数就好了

pushdown的时候忘更新子节点add值了,导致很弱很弱的数据过不去,看来以后做题得出普通数据验证啊= =

#include<stdio.h>
#define lson l,mid,rt*2
#define rson mid+1,r,rt*2+1
#define X 400010
int a[X],add[X],ll,rr,c;
void pushup(int rt){
	a[rt]=a[rt*2]|a[rt*2+1];
}
void pushdown(int rt){
	if(add[rt]){
		a[rt*2]=a[rt*2+1]=add[rt];
		add[rt*2]=add[rt*2+1]=add[rt];
		add[rt]=0;
	}
}
void build(int l,int r,int rt){
	a[rt]=2;add[rt]=0;
	if(l==r)return ;
	int mid=l+r>>1;
	build(lson);
	build(rson);
}
void update(int l,int r,int rt){
	if(ll<=l&&rr>=r){
		a[rt]=add[rt]=1<<c;
		return ;
	}
	pushdown(rt);
	int mid=l+r>>1;
	if(ll<=mid)update(lson);
	if(rr> mid)update(rson);
	pushup(rt);
}
int que(int l,int r,int rt){
	if(ll<=l&&rr>=r)return a[rt];
	pushdown(rt);
	int mid=l+r>>1;
	int as=0;
	if(ll<=mid)as=que(lson);
	if(rr>mid)as|=que(rson);
	return as;
}
int main(){
	int i,n,t,q,cnt;
	char s[5];
	while(~scanf("%d%d%d",&n,&t,&q)){
		build(1,n,1);
		while(q--){
			scanf("%s%d%d",s,&ll,&rr);
			if(ll>rr){t=ll;ll=rr;rr=t;}
			if(s[0]=='C'){
				scanf("%d",&c);
				update(1,n,1);
			}
			else{
				t=que(1,n,1);
				for(cnt=i=0;i<32;i++)
				    if((1<<i)&t)cnt++;
				printf("%d\n",cnt);
			}
		}
	}
	return 0;
}


 

你可能感兴趣的:(POJ 2777 Count Color)