题目大意:
个板砖,按序排列以及编号,颜色初始时都为
,有
种颜色,也是从
到
编号,
个询问,
每个询问可以支持两种操作:
①
将第
个板砖到第
个板砖的颜色变成
②
问第
个板砖到第
个板砖有多少种颜色
分析:
线段树处理,
每个节点用一个数去记录一下这个结点代表的区间有多少种颜色,因为颜色种类很少
然后就是正常的区间修改,注意修改的时候打lazy即可
然后查询的时候的
可能
,这时候不合法要交换顺序(坑)
然后回答区间颜色种类的时候就是找到对应区间的状态 或起来以后即为答案
注意某个区间只有一种颜色就直接返回该区间的状态即可,因为它所有的子区间都是只有这种颜色
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define lson(x) x * 2
#define rson(x) x * 2 + 1
#define der(x) 1 << x
#define N 100005
using namespace std;
struct Node { int lzy, tot; }a[N*5];
int n, m, q, ans;
void Update(int x)
{
a[x].tot = a[lson(x)].tot | a[rson(x)].tot;
}
void pushdown(int x)
{
if (a[x].lzy != -1) { a[lson(x)].tot = a[rson(x)].tot = der(a[x].lzy), a[lson(x)].lzy = a[rson(x)].lzy = a[x].lzy; a[x].lzy = -1; }
}
int Get_num(int x)
{
int num = 0;
for (; x; x >>= 1) num = num + (x & 1 ? 1 : 0);
return num;
}
void Build(int G, int l, int r)
{
a[G].tot = 1; a[G].lzy = -1;
if (l == r) return;
int mid = (l + r) >> 1;
Build(lson(G), l, mid);
Build(rson(G), mid + 1, r);
}
void change(int G, int l, int r, int liml, int limr, int cnum)
{
if (l == liml && r == limr) { a[G].tot = der(cnum), a[G].lzy = cnum; return; }
int mid = (l + r) >> 1;
pushdown(G);
if (limr <= mid) change(lson(G), l, mid, liml, limr, cnum);
else if (liml > mid) change(rson(G), mid + 1, r, liml, limr, cnum);
else change(lson(G), l, mid, liml, mid, cnum), change(rson(G), mid + 1, r, mid + 1, limr, cnum);
Update(G);
}
void query(int G, int l, int r, int liml, int limr)
{
if (Get_num(a[G].tot) == 1) { ans = ans | a[G].tot; return; }
if (l == liml && r == limr) { ans = ans | a[G].tot; return; }
int mid = (l + r) >> 1;
pushdown(G);
if (limr <= mid) query(lson(G), l, mid, liml, limr);
else if (liml > mid) query(rson(G), mid + 1, r, liml, limr);
else query(lson(G), l, mid, liml, mid), query(rson(G), mid + 1, r, mid + 1, limr);
Update(G);
}
void Get_Answer(int l, int r)
{
ans = 0;
query(1, 1, n, l, r);
printf("%d\n", Get_num(ans));
}
int main()
{
scanf("%d %d %d", &n, &m, &q);
Build(1, 1, n);
char opt[2]; int l, r, x;
rep(i, 1, q)
{
scanf("%s %d %d", opt, &l, &r);
if (l > r) swap(l, r);
if (opt[0] == 'C') { scanf("%d", &x); change(1, 1, n, l, r, x - 1); }
else if (opt[0] == 'P') Get_Answer(l, r);
}
return 0;
}