题意
给定一个区间长度为l,共有t种颜色,o个操作。
C a b x 表示把a到b染成第x种颜色,P a b 表示查询a b间共有几种颜色。
初始状态下所有颜色为1,我就是因为这一点WA了几次
题解
t最大才30,颜色直接二进制压缩即可,不要每次修改a b间所有的点,lazy一下就好了
常数巨大的丑陋代码
# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <algorithm>
using namespace std;
# define IL inline
# define RG register
# define UN unsigned
# define ll long long
# define rep(i, a, b) for(RG int i = a; i <= b; i++)
# define per(i, a, b) for(RG int i = b; i >= a; i--)
# define mem(a, b) memset(a, b, sizeof(a))
# define max(a, b) ((a) > (b)) ? (a) : (b)
# define min(a, b) ((a) < (b)) ? (a) : (b)
# define Swap(a, b) a ^= b, b ^= a, a ^= b;
IL int Get(){
RG char c = '!'; RG int x = 0, z = 1;
while(c != '-' && (c < '0' || c > '9')) c = getchar();
if(c == '-') z = -1, c = getchar();
while(c >= '0' && c <= '9') x=x*10+c-'0', c = getchar();
return x*z;
}
const int MAXM = 2000001;
struct Tree{
int l, r, cover, color;
} tree[MAXM];
//color状压颜色
IL void Updata(RG int now){
tree[now].color = tree[now<<1].color|tree[now<<1|1].color;
}
IL void Pushdown(RG int now){
if(!tree[now].cover) return;
tree[now<<1|1].cover = tree[now<<1].cover = 1;
tree[now<<1|1].color = tree[now<<1].color = tree[now].color;
tree[now].cover = 0;
}
IL void Build(RG int now, RG int l, RG int r){
tree[now] = (Tree) {l, r, 1, 1};
if(l == r) return;
RG int mid = l+r>>1;
Build(now<<1, l, mid); Build(now<<1|1, mid+1, r);
Updata(now);
}
IL int Query(RG int now, RG int l, RG int r){
if(tree[now].cover || (tree[now].l == l && tree[now].r == r)) return tree[now].color;
Pushdown(now);
RG int mid = tree[now].l+tree[now].r>>1, t = 0;
if(mid < l) t = Query(now<<1|1, l, r);
if(mid >= l && mid < r) t = Query(now<<1, l, mid)|Query(now<<1|1, mid+1, r);
if(mid >= r) t = Query(now<<1, l, r);
Updata(now);
return t;
}
IL void Add(RG int now, RG int l, RG int r, RG int x){
if(tree[now].l == l && tree[now].r == r){
tree[now].cover = 1; tree[now].color = x;
return;
}
if(tree[now].color == x) return;
Pushdown(now);
RG int mid = tree[now].l+tree[now].r>>1;
if(mid < l) Add(now<<1|1, l, r, x);
if(mid >= l && mid < r) Add(now<<1, l, mid, x), Add(now<<1|1, mid+1, r, x);
if(mid >= r) Add(now<<1, l, r, x);
Updata(now);
}
int main(){
RG int l = Get(), t = Get(), o = Get();
Build(1, 1, l);
rep(i, 1, o){
char c;
scanf(" %c", &c);
if(c == 'C'){
RG int a = Get(), b = Get(), x = Get();
Add(1, a, b, 1<<(x-1));
}
else if(c == 'P'){
RG int a = Get(), b = Get();
RG int t = Query(1, a, b), ans = 0;
while(t){
ans++;
t -= (t&-t);
}
printf("%d
", ans);
}
}
return 0;
}