有两种操作,一个是更新区间内颜色,一个是询问区间内不同颜色的个数
因为颜色最多只有30种,所以把区间内颜色数压成一个数字即可,如果(1<<i)为1的话,就表示有这个颜色,更新时只要将儿子的这个值或运算一下就好了
因为是区间更新,所以再加个延时标记就好了。
/*===============*\
| *** *** *** *** |
| * ** * * * |
| *** *** * *** |
| ID: ZERO |
| LANG: C++ |
\*===============*/
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <string>
#include <cassert>
using namespace std;
#define mod (int)(1e9+7)
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define maxn 100001
int col[maxn<<2];
bool up[maxn<<2];
int upit[maxn<<2];
void PushUP(int rt) { //向上更新
col[rt] = col[rt<<1]|col[rt<<1|1];
}
void PushDown(int rt,int l,int r,int now){ //向下更新
col[now]=col[rt];
if(l!=r){
up[now]=true;
upit[now]=col[rt];
}
}
void build(int co,int l,int r,int rt) {//建树
up[rt]=false;
if (l == r) {
col[rt]=co;
return ;
}
int m = (l + r) >> 1;
build(co,lson);
build(co,rson);
PushUP(rt);
}
void update(int ll,int rr,int sc,int l,int r,int rt) {//更新
if (l >=ll && r<=rr) {
col[rt] = sc;
if(l!=r) {up[rt]=true;upit[rt]=sc;} //延时标记
return ;
}
int m=(l+r) >> 1;//middle
if(up[rt]){//触发延时标记
PushDown(rt,lson);
PushDown(rt,rson);
up[rt]=false;
}
if (ll<=m&&rr>=l) update(ll,rr , sc , lson);
if (ll<=r&&rr>=m+1) update(ll,rr , sc , rson);
PushUP(rt);
}
int query(int L,int R,int l,int r,int rt) {//询问
if (L <= l && r <= R) {
return col[rt];
}
int m=(l+r) >> 1;//middle
if(up[rt]){
PushDown(rt,lson);
PushDown(rt,rson);
up[rt]=false;
}
int ret = 0;
if (L <= m) ret = ret|query(L,R,lson);
if (R > m) ret = ret|query(L,R,rson);
return ret;
}
char s[2];
int main(){
int n,m,t;
while (~scanf("%d%d%d",&n,&t,&m)) {
build(1,1,n,1);//建树
while (m--) {
int l,r,co;
scanf("%s%d%d",s,&l,&r);
int tt;
if(l>r) tt=l,l=r,r=tt;// A may be larger than B 这条件你妹的!
if(s[0]=='C'){
scanf("%d",&co);
update(l,r,1<<(co-1),1,n,1);
}
else{
int nn=query(l,r,1,n,1),ans=0;
for(int i=0;i<t;i++){
if(nn&(1<<i)) ans++;
}
printf("%d\n",ans);
}
}
}
return 0;
}