一直以来就是这么写,很稳。
大晚上先贴个代码吧,下次给加注释。
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;
}