题目
求区间内有多少种不同的颜色。
分析
线段树,做来做去发现还要用懒标记,标记是否为旧的涂色。
代码
#include <cstdio>
#include <cctype>
using namespace std;
int w[400001],l,t,m,ans,now;bool blag[400001],flag[41];
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void build(int k,int l,int r){//建树
w[k]=1; blag[k]=1;
if (r-l>1)
build(k<<1,l,(l+r)>>1),
build((k<<1)+1,((l+r)>>1)+1,r);
}
void update(int k,int l,int r,int x,int y,int z){//修改
if (l==x&&r==y) w[k]=z,blag[k]=1;
else{
if (blag[k]){//懒标记
w[k<<1]=w[(k<<1)+1]=w[k];
blag[k<<1]=blag[(k<<1)+1]=blag[k]; blag[k]=0;
}
int mid=(l+r)>>1;
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update((k<<1)+1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),update((k<<1)+1,mid+1,r,mid+1,y,z);
}
}
void getf(int k,int l,int r,int x,int y){//查找
if (blag[k]){flag[w[k]]=1;}
else{
int mid=(l+r)>>1;
if (y<=mid) getf(k<<1,l,mid,x,y);
else if (x>mid) getf((k<<1)+1,mid+1,r,x,y);
else getf(k<<1,l,mid,x,mid),getf((k<<1)+1,mid+1,r,mid+1,y);
}
}
int main(){
l=in(); t=in(); m=in();
build(1,1,l);
while (m--){
char q=getchar();
int x=in(); int y=in();
if (q=='C'){
int z=in();
update(1,1,l,x,y,z);
}
else {
for (int i=0;i<=30;i++) flag[i]=0;
getf(1,1,l,x,y); ans=0;
for (int i=1;i<=t;i++) ans+=flag[i];
printf("%d\n",ans);
}
}
return 0;
}