|
|
#include <cstdio>
|
|
|
#include <cstring>
|
|
|
#include <algorithm>
|
|
|
#include <iostream>
|
|
|
|
|
|
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;
|
|
|
} |