区间更新 + 二进制小优化
每个key值表示当前节点存在的颜色的种类个数(因为T<=30,所以用二进制保存)
#include <iostream>
#include <cstdio>
#include <cstring>
#define lson l, mid, dex<<1
#define rson mid+1, r, dex<<1|1
#define havemid int mid = (l + r)>>1
using namespace std;
const int mx = 100010;
int key[mx<<2];
int flag[mx<<2];
void Push_down(int dex)
{
if(flag[dex] != -1)
{
key[dex<<1] = key[dex<<1|1] = key[dex];
flag[dex<<1] = flag[dex<<1|1] = flag[dex];
flag[dex] = -1;
return ;
}
}
void Push_up(int dex)
{
key[dex] = 0;
key[dex] |= key[dex<<1];
key[dex] |= key[dex<<1|1];
return ;
}
void build(int l,int r,int dex)
{
key[dex] |= (1<<1);
if(l == r) return;
havemid;
build(lson);
build(rson);
}
void check(int x, int T)
{
int ans = 0;
for(int i=1; i<=T; i++)
if(x & (1<<i)) ans++;
printf("%d\n",ans);
}
void updata(int L, int R, int c, int l, int r, int dex)
{
if(L<=l && R>=r)
{
flag[dex] = 1;
key[dex] = 0;
key[dex] |= (1<<c);
return;
}
Push_down(dex);
havemid;
if(L<=mid) updata(L,R,c,lson);
if(R> mid) updata(L,R,c,rson);
Push_up(dex);
}
int query(int L, int R, int l, int r, int dex)
{
if(L<=l && R>=r)
return key[dex];
Push_down(dex);
havemid;
int tem = 0;
if(L <= mid) tem |= query(L, R, lson);
if(R > mid) tem |= query(L, R, rson);
return tem;
}
int main()
{
// freopen("2777.txt","r",stdin);
int n,T,O;
while(~scanf("%d %d %d",&n, &T, &O))
{
memset(key,0,sizeof(key));
memset(flag, -1 , sizeof(flag));
build(1, n, 1);
for(int i=1; i<=O; i++)
{
getchar();
char ch;
int a,b,c;
scanf("%c",&ch);
if(ch == 'C')
{
scanf("%d %d %d",&a,&b,&c);
if(a > b) swap(a , b);
updata(a, b, c, 1, n, 1);
}
else
{
scanf("%d %d",&a,&b);
if(a > b) swap(a , b);
check(query(a, b, 1, n, 1), T);
}
}
}
return 0;
}