P1558 色板游戏¶
题目背景¶
阿宝上学了,今天老师拿来了一块很长的涂色板。
题目描述¶
色板长度为 \(L\),\(L\) 是一个正整数,所以我们可以均匀地将它划分成 \(L\) 块 \(1\) 厘米长的小方格。并从左到右标记为 \(1, 2, \dots, L\)。
现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:
C A B C
指在 \(A\) 到 \(B\) 号方格中涂上颜色 \(C\)。P A B
指老师的提问:\(A\) 到 \(B\) 号方格中有几种颜色。
学校的颜料盒中一共有 \(T\) 种颜料。为简便起见,我们把他们标记为 \(1, 2, \dots, T\)。开始时色板上原有的颜色就为 \(1\) 号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?
输入格式¶
第一行有3个整数 \(L (1 \le L \le 10^5)\),\(T (1 \le T \le 30)\) 和 \(O (1 \le O \le 10^5)\)。 在这里 \(O\) 表示事件数。
接下来 \(O\) 行, 每行以 C A B C
或 P A B
的形式表示所要做的事情(这里 \(A, B, C\) 为整数, 可能 \(A> B\),这样的话需要你交换 \(A\) 和 \(B\))。
输出格式¶
对于老师的提问,做出相应的回答。每行一个整数。
输入输出样例 #1¶
输入 #1¶
1 2 3 4 5 |
|
输出 #1¶
1 2 |
|
题目分析¶
目的:对于老师的提问,进行相应的回答,统计出 \(A\) 到 \(B\) 号方格中有几种颜色。
由题目信息可知,核心动作有两个:
C A B C
: 区间修改,将\([A,B]\)中的内容修改为 \(C\)。P A B
: 区间查询,统计\([A,B]\)中不同的数字个数。
整体来看的话是一个动态的序列问题,由此联想到线段树。
那么,关键问题就变成了如何利用线段树进行区间内不同元素个数的统计,以及进行区间整体修改这两个操作。
首先,考虑如何实现区间查询。观察到颜色的种类只有30个,数量较少,可以利用位运算来进行统计。可以让每种颜色分别对应上二进制中的一位,如1号颜色对应\(0000\cdots 0001\),2号颜色对应\(0000\cdots 0010\),以此类推。这样的话,整体的区间颜色填涂情况就可以利用按位或进行合并,区间内不同颜色的数量就变成了二进制中1的总数了。
1 2 3 |
|
之后,考虑如何进行区间整体颜色的修改。操作中的颜色修改是覆盖类型的修改,所以可以考虑直接进行赋值覆盖。另外需要注意的是,为了加速整体修改,往往加入延迟标记的技巧,在对标记值进行下方时,为了避免覆盖动作影响实际内容,当延迟标记为空时则不进行下放动作。
1 2 3 4 5 6 7 8 9 10 11 |
|
代码实现¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
|