题意:经过一系列操作之后,求可以看见的颜色数
做法:一开始2了用了个数组简单统计了一下,果断TLE,所以后来只能想个法子,用节点记录区间中还有颜色的种类,用二进制数压缩即可
#include<cstdio>
#include<cstring>
#define left l,m,x<<1
#define right m+1,r,x<<1|1
const int LMT=100003;
int colo[LMT<<2],ans,L,T;
bool cov[LMT<<2],vis[35];
//扳子和段的区别啊
void cut(int x)
{
if(cov[x])
{
cov[x<<1]=cov[x<<1|1]=cov[x];
colo[x<<1]=colo[x<<1|1]=colo[x];
cov[x]=0;
}
}
void update(int co,int L,int R,int l,int r,int x)
{
if(L<=l&&r<=R)
{
colo[x]=1<<co;
cov[x]=1;
return;
}
cut(x);
int m=(l+r)>>1;
if(L<=m)update(co,L,R,left);
if(R>m)update(co,L,R,right);
colo[x]=colo[x<<1]|colo[x<<1|1];
}
void query(int L,int R,int l,int r,int x)
{
if(L<=l&&r<=R)
{
for(int i=0;i<T;i++)
if(1<<i&colo[x]&&vis[i]==0)
{
vis[i]=1;
ans++;
}
return ;
}
if(l==r)return;
cut(x);
int m=(l+r)>>1;
if(L<=m)query(L,R,left);
if(R>m)query(L,R,right);
}
int main(void)
{
int O,l,r,d;
char op;
scanf("%d%d%d",&L,&T,&O);
colo[1]=1;
cov[1]=1;
while(O--)
{
op=getchar();
while(op!='C'&&op!='P')op=getchar();
if(op=='C')
{
scanf("%d%d%d",&l,&r,&d);
d--;
if(l>r)
{
int t=l;
l=r;r=t;
}
update(d,l,r,1,L,1);
}
else
{
scanf("%d%d",&l,&r);
if(l>r)
{
int t=l;
l=r;r=t;
}
memset(vis,0,sizeof(vis));
ans=0;
query(l,r,1,L,1);
printf("%d\n",ans);
}
}
return 0;
}