一直以来就是这么写,很稳。
大晚上先贴个代码吧,下次给加注释。
const int Maxn = 1e5 + 10;
struct Seg{
int Left, Right;
int col;
int _col;
}node[Maxn<<2];
void pushUp(int num){
node[num].col = node[num<<1].col|node[num<<1|1].col;
}
void pushDown(int num){
if(node[num]._col){
node[num<<1].col = node[num<<1|1].col = (1<<node[num]._col);
node[num<<1]._col = node[num<<1|1]._col = node[num]._col;
node[num]._col = 0;
}
}
void Build(int num, int Left, int Right){
node[num].Left = Left;
node[num].Right = Right;
node[num]._col = 0;
if(Left == Right){
node[num].col = (1<<1);
return;
}
int Mid = (node[num].Left + node[num].Right) >> 1;
Build(num<<1, Left, Mid);
Build(num<<1|1, Mid+1, Right);
pushUp(num);
}
void update(int num, int s, int t, int col){
if(node[num].Left >= s && node[num].Right <= t){
node[num].col = (1<<col);
node[num]._col = col;
return;
}
pushDown(num);
int Mid = (node[num].Left + node[num].Right) >> 1;
if(Mid >= t) update(num<<1, s, t, col);
else if(Mid < s) update(num<<1|1, s, t, col);
else{
update(num<<1, s, Mid, col);
update(num<<1|1, Mid+1, t, col);
}
pushUp(num);
}
int query(int num, int s, int t){
if(node[num].Left >= s && node[num].Right <= t)
return node[num].col;
pushDown(num);
int Mid = (node[num].Left + node[num].Right) >> 1;
if(Mid >= t) return query(num<<1, s, t);
else if(Mid < s) return query(num<<1|1, s, t);
else{
int x = query(num<<1, s, Mid);
int y = query(num<<1|1, Mid+1, t);
return x|y;
}
}
int solve(int s, int t, int T){
int col = query(1, s, t);
int num = 0;
for(int i=1;i<=T;i++){
if(col & (1<<i)) num++;
}
return num;
}
int main(){
char op[5];
int n, T, q;
int s, t, col;
scanf("%d%d%d", &n, &T, &q);
Build(1, 1, n);
for(int i=1;i<=q;i++){
scanf("%s", op);
if(op[0] == 'C'){
scanf("%d%d%d", &s, &t, &col);
if(s > t) swap(s, t);
update(1, s, t, col);
}
else{
scanf("%d%d", &s, &t);
if(s > t) swap(s, t);
printf("%d\n", solve(s, t, T));
}
}
return 0;
}