思路:
直接开权值线段树维护就好了
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1e5 + 2;
int n, m, K;
struct node {
bool v[31];
int flag;
}tr[MAXN << 2];
int g[31];
inline void down(register int k, register int l, register int r) {
register int mid = l + r >> 1, left = (k << 1), right = (k << 1 | 1);
tr[left].flag = tr[right].flag = tr[k].flag;
memset(tr[left].v, 0, sizeof(tr[left].v));
memset(tr[right].v, 0, sizeof(tr[right].v));
tr[left].v[tr[k].flag] = tr[right].v[tr[k].flag] = 1;
tr[k].flag = 0;
}
inline void mix_(register int k) {
register int left = (k << 1), right = (k << 1 | 1);
for(register int i = 1; i <= K; i ++) tr[k].v[i] = tr[left].v[i] | tr[right].v[i];
}
inline void build(register int k, register int l, register int r) {
if(l > r) return ;
tr[k].v[1] = 1;
register int mid = l + r >> 1;
if(l == r) return ;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
}
inline void change(register int k, register int l, register int r, register int x, register int y, register int z) {
if(x <= l && r <= y) {
memset(tr[k].v, 0, sizeof(tr[k].v));
tr[k].v[z] = 1;
tr[k].flag = z;
return ;
}
if(tr[k].flag != 0) down(k, l, r);
register int mid = l + r >> 1;
if(x <= mid) change(k << 1, l, mid, x, y, z);
if(y > mid) change(k << 1 | 1, mid + 1, r, x, y, z);
mix_(k);
}
inline void query_(register int k, register int l, register int r, register int x, register int y) {
if(x <= l && r <= y) {
for(register int i = 1; i <= K; i ++) g[i] |= tr[k].v[i];
return ;
}
if(tr[k].flag != 0) down(k, l, r);
register int mid = l + r >> 1;
if(x <= mid) query_(k << 1, l, mid, x, y);
if(y > mid) query_(k << 1 | 1, mid + 1, r, x, y);
mix_(k);
}
int main() {
scanf("%d%d%d", &n, &m, &K);
build(1, 1, n);
for(register int i = 1; i <= m; i ++) {
string s;
register int l, r, x;
cin>>s;
scanf("%d%d", &l, &r);
if(s == "C") {
scanf("%d", &x);
change(1, 1, n, l, r, x);
}
else {
memset(g, 0, sizeof(g));
query_(1, 1, n, l, r);
register int sum = 0;
for(register int i = 1; i <= K; i ++) if(g[i]) sum ++;
printf("%d\n", sum);
}
}
return 0;
}