#include #include #include #include using namespace std; const int N = 100010; #define ls u << 1 #define rs u << 1 | 1 struct Node { int l, r; int add, sum; } tr[N << 2]; void pushup(int u) { tr[u].sum = tr[ls].sum | tr[rs].sum; //因为是模拟二进制的操作,所以采用 或 运算即可完成拼接操作 } void pushdown(int u) { if (tr[u].add) { tr[ls].add = tr[rs].add = tr[u].add; tr[ls].sum = tr[rs].sum = tr[u].add; tr[u].add = 0; } } void build(int u, int l, int r) { tr[u].l = l, tr[u].r = r; if (l == r) { tr[u].sum = 1; // sum记录的其实是一个30位的二进制压缩模拟数字,此时置为1表示最后一位即0位为1,是默认的颜色 return; } int mid = (l + r) >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); pushup(u); } void modify(int u, int l, int r, int c) { if (l <= tr[u].l && tr[u].r <= r) { tr[u].add = 1 << (c - 1); tr[u].sum = 1 << (c - 1); return; } pushdown(u); int mid = tr[u].l + tr[u].r >> 1; if (l <= mid) modify(u << 1, l, r, c); if (r > mid) modify(u << 1 | 1, l, r, c); pushup(u); } int query(int u, int l, int r) { if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum; int ans = 0; pushdown(u); int mid = tr[u].l + tr[u].r >> 1; if (l <= mid) ans = query(u << 1, l, r); if (r > mid) ans = ans | query(u << 1 | 1, l, r); return ans; } //手工版本数字1个数 int count(int x) { int cnt = 0; while (x) { cnt++; x -= (x & -x); } return cnt; } int main() { //加快读入 ios::sync_with_stdio(false), cin.tie(0); int n, t, m; //区间[1,n],t种颜色,m个操作 cin >> n >> t >> m; //构建 build(1, 1, n); while (m--) { char op; int l, r; cin >> op >> l >> r; if (l > r) swap(l, r); //坑点题目没说哪个大哪个小,需要特判 if (op == 'C') { int c; cin >> c; modify(1, l, r, c); } else { int ans = query(1, l, r); int cnt = count(ans); //获取某个数二进制位1的个数 printf("%d\n", cnt); } } return 0; }