题目大意:给你一个长度为n的线段(n<1000000),还有t种颜料(m<30)。有以下两种操作:
#include<stdio.h>
#include<string.h>
#define maxn 100010
struct node
{
int l,r;//线段树区间
int mid;//线段树区间中间值
int mark;//
}p[maxn<<2];
int v[32];
void build(int id,int l,int r)
{
p[id].l=l;
p[id].r=r;
p[id].mid=(l+r)>>1;
p[id].mark=1;
if(l==r) return;
build(2*id,l,p[id].mid);
build(2*id+1,p[id].mid+1,r);
}
void update(int id,int l,int r,int val)
{
if(p[id].l==l&&p[id].r==r){
p[id].mark=val;
return;
}
if(p[id].mark==val) return;
if(p[id].mark!=0){
p[id*2].mark=p[id].mark;
p[id*2+1].mark=p[id].mark;
p[id].mark=0;
}
if(p[id].mid>=r) update(2*id,l,r,val);
else if(p[id].mid<l) update(id*2+1,l,r,val);
else{
update(id*2,l,p[id].mid,val);
update(id*2+1,p[id].mid+1,r,val);
}
}
void query(int id,int l,int r)
{
if(p[id].mark!=0){
v[p[id].mark]=1;
return;
}
if(p[id].mid>=r) query(id*2,l,r);
else if(p[id].mid<l) query(id*2+1,l,r);
else{
query(id*2,l,p[id].mid);
query(id*2+1,p[id].mid+1,r);
}
}
int main()
{
int n,m,b,c,d,i,t,tmp,count;
char str[5];
scanf("%d%d%d",&n,&m,&t);
build(1,1,n);
for(int j=0;j<t;j++)
{
scanf("%s%d%d",str,&b,&c);
if(b>c){
tmp=b;
b=c;
c=tmp;
}
if(str[0]=='C'){
scanf("%d",&d);
update(1,b,c,d);
}
else{
memset(v,0,sizeof(v));
query(1,b,c);
count=0;
for(i=1;i<=m;i++)
if(v[i]) count++;
printf("%d\n",count);
}
}
return 0;
}