第一个线段树搞了好多天啊!!!!!!!!!!!!!!!!!
线段树就是个二叉树非叶子节点都有两个儿子。
线段树就是每个节点都是一条线段神马的父亲线段(非叶子)包含儿子线段。
这个题目就是更新的时候要注意
0 == color 就是代表有多种颜色在该线段上
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 int const max_length = 400005;
6 int const max_color = 40;
7 struct Node{
8 int left, right;
9 int color;
10 void set(int _left, int _right, int _color = 1){
11 left = _left;
12 right = _right;
13 color = _color;
14 }
15 }st[max_length];
16 int used[max_color];
17
18 void init(int t, int left, int right);
19 void color(int t, int left, int right, int color);
20 void in_bucket(int t, int left, int right);
21
22 int main(void){
23 int l, t, o;
24 char buff[10];
25 int left, right, _color;
26
27 while(3 == scanf("%d%d%d", &l, &t, &o)){
28 init(1, 1, l + 1);
29 for(int i = 0; i < o; ++i){
30 scanf("%s", buff);
31 if('C' == buff[0]){
32 scanf("%d%d%d", &left, &right, &_color);
33 if(left > right)
34 std::swap(left, right);
35 color(1, left, right + 1, _color);
36 } else if('P' == buff[0]){
37 scanf("%d%d", &left, &right);
38 memset(used, 0, sizeof(used));
39 in_bucket(1, left, right + 1);
40 printf("%d\n", static_cast<int>(std::count(used, used + max_color, 1)));
41 }
42 }
43 }
44
45 return 0;
46 }
47
48 void init(int t, int left, int right){
49 st[t].set(left, right);
50 int mid = (left + right) >> 1;
51 if(mid == left)
52 return ;
53 init(t << 1, left, mid);
54 init(t << 1 | 1, mid, right);
55 }
56
57 void color(int t, int left, int right, int _color){
58 if(st[t].color == _color)
59 return ;
60 if(st[t].left == left && st[t].right == right){
61 st[t].color = _color;
62 return ;
63 }
64 if(0 != st[t].color){
65 st[t << 1].color = st[t].color;//保持非涂色区域本色(首先木有写着里无数WA啊)
66 st[t << 1 | 1].color = st[t].color;//保持非涂色区域本色
67 st[t].color = 0;
68 }
69 int mid =(st[t].left + st[t].right) >> 1;
70 if(mid >= right)
71 color(t << 1, left, right, _color);//在左儿子
72 else if(mid <= left)
73 color(t << 1 | 1, left, right, _color);//在右儿子
74 else {
75 color(t << 1, left, mid, _color);//在左儿子
76 color(t << 1 | 1, mid, right, _color);//在右儿子
77 }
78 }
79
80 void in_bucket(int t, int left, int right){
81 if(st[t].color > 0){
82 used[st[t].color] = 1;
83 return ;
84 }
85 int mid = (st[t].left + st[t].right) >> 1;
86 if(right <= mid)
87 in_bucket(t << 1, left, right);
88 else if(left >= mid)
89 in_bucket(t << 1 | 1, left, right);
90 else {
91 in_bucket(t << 1, left, mid);
92 in_bucket(t << 1 | 1, mid, right);
93 }
94 }