题意
给定一个区间长度为l,共有t种颜色,o个操作。
C a b x 表示把a到b染成第x种颜色,P a b 表示查询a b间共有几种颜色。 初始状态下所有颜色为1,题解
t最大才30,颜色直接二进制压缩即可,不要每次修改a b间所有的点,lazy一下就好了
常数巨大的丑陋代码
# include# include # include # include # include 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\n", ans); } } return 0;}