和poj2528类似,不过不用离散化,也可以用位运算加速(因为颜色总共不过30种)
#include<cstdio>
#include<cstdlib>
#include<cstring>
bool visit[35];
int ans;
struct Tree{
int s;
int t;
int c;
}tree[270010];
void build(int s,int t,int id){
tree[id].s=s;
tree[id].t=t;
tree[id].c=1;
if(s!=t){
int mid=(tree[id].s+tree[id].t)>>1;
build(s,mid,id*2);
build(mid+1,t,id*2+1);
}
}
void insert(int s,int t,int id,int colour){
if(tree[id].s==s && tree[id].t==t){
tree[id].c=colour;
return ;
}
if(colour==tree[id].c)
return ;
if(tree[id].c>0){
tree[id*2].c=tree[id].c;
tree[id*2+1].c=tree[id].c;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(mid<s)
insert(s,t,id*2+1,colour);
else if(mid>=t)
insert(s,t,id*2,colour);
else{
insert(s,mid,id*2,colour);
insert(mid+1,t,id*2+1,colour);
}
if(tree[id*2+1].c!=tree[id*2].c || !tree[id*2+1].c || !tree[id*2].c)
tree[id].c=0;
}
void query(int s,int t,int id){
if(tree[id].c!=0){
if(!visit[tree[id].c]){
visit[tree[id].c]=1;
ans++;
}
return;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(mid<s)
query(s,t,id*2+1);
else if(mid>=t)
query(s,t,id*2);
else{
query(s,mid,id*2);
query(mid+1,t,id*2+1);
}
}
int main(){
int n,i,a,b,c,m,cc;
scanf("%d %d %d",&n,&cc,&m);
build(1,n,1);
for(i=1;i<=m;i++){
char ss[5];
scanf("%s",ss);
if(ss[0]=='C'){
scanf("%d %d %d",&a,&b,&c);
if(a>b){
int tem;
tem=a,a=b;b=tem;
}
insert(a,b,1,c);
}
else{
scanf("%d %d",&a,&b);
memset(visit,0,sizeof(visit));
ans=0;
if(a>b){
int tem;
tem=a,a=b;b=tem;
}
query(a,b,1);
printf("%d\n",ans);
}
}
}