继续线段树。
开始直接统计无悬念超时,后来看了某大牛的代码用了位运算把颜色的种类存到一个整形变量里才过。
1 #include <stdio.h>
2 #include <string.h>
3 typedef struct{
4 int left,right,color;
5 bool cover;
6 }SegTree;
7 SegTree board[450000];
8 void createSegTree(int root, int left, int right){
9 int mid;
10 board[root].left = left;
11 board[root].right = right;
12 board[root].color = 1 << 1;
13 board[root].cover = true;
14 if(left == right)
15 return;
16 mid = left + right >> 1;
17 createSegTree(root << 1, left, mid);
18 createSegTree(root << 1 | 1, mid + 1, right);
19 }
20
21 void updateSegTree(int root, int left, int right, int color){
22 int mid = board[root].left + board[root].right >> 1;
23 if(left <= board[root].left && right >= board[root].right){
24 board[root].cover = true;
25 board[root].color = 1 << color;
26 return;
27 }
28 if(board[root].cover){
29 board[root << 1].color = board[root << 1 | 1].color = board[root].color;
30 board[root << 1].cover = board[root << 1 | 1].cover = true;
31 board[root].cover = false;
32 }
33 if(left <= mid)
34 updateSegTree(root << 1, left, right, color);
35 if(right > mid)
36 updateSegTree(root << 1 | 1, left, right, color);
37 board[root].color = board[root << 1].color | board[root << 1 | 1].color;
38 }
39
40 int queryColorKind(int root, int left, int right){
41 int color;
42 int mid = board[root].left + board[root].right >> 1;
43 if(board[root].left == left && board[root].right == right)
44 return board[root].color;
45 if(board[root].cover){
46 board[root << 1].color = board[root << 1 | 1].color = board[root].color;
47 board[root << 1].cover = board[root << 1 | 1].cover = true;
48 board[root].cover = false;
49 }
50 if(left > mid)
51 return queryColorKind(root << 1 | 1, left, right);
52 else if(right <= mid)
53 return queryColorKind(root << 1, left, right);
54 else{
55 color = queryColorKind(root << 1, left, mid);
56 return color | queryColorKind(root << 1 | 1, mid + 1, right);
57 }
58 }
59
60 int countBit(int ans){
61 int i,res = 0;
62 for(i = 0; i <32; i++){
63 if(ans & 1)
64 res++;
65 ans = ans >> 1;
66 }
67 return res;
68 }
69 int main (void){
70 int root = 1;
71 int i,left,right,color,L,T,O,ans;
72 char order;
73 // freopen("in.txt","r",stdin);
74 while(~scanf("%d%d%d",&L,&T,&O)){
75 createSegTree(root, 1, L);
76 for(i = 0; i < O; i++){
77 getchar();
78 scanf("%c",&order);
79 if(order == 'C'){
80 scanf("%d%d%d",&left,&right,&color);
81 if(left > right)
82 left ^= right ^= left ^= right;
83 updateSegTree(root, left, right, color);
84 }
85 else{
86 scanf("%d%d",&left,&right);
87 if(left > right)
88 left ^= right ^= left ^= right;
89 if(left != right)
90 ans = queryColorKind(root,left,right);
91 printf(left == right ? "1\n":"%d\n",countBit(ans));
92 }
93 }
94 }
95 return 0;
96 }