这是一道非常好的题,值得思考。题目要求维护区间内颜色的种数,那该如何表示一个区间内颜色的种数呢?
其实我们没有必要维护区间内颜色的种数,而是维护这ttt种颜色是否出现过。由于只有出现过和没出现两种状态,所以可以用状态压缩,用一个TTT位二进制数来表示,从右往左第kkk位为111表示在此区间颜色kkk出现过,反之没有出现过;
接下来是修改和查询操作:
修改:完全包含时直接设为2v−12^{v-1}2v−1,即1<<(v−1)1<<(v-1)1<<(v−1),充分利用了位运算的优势;若未完全包含,则使用位或运算,这样就不会重复计数,即将tree[id]tree[id]tree[id]设为tree[id<<1] ∣ tree[id<<1∣1]tree[id<<1]\;|\; tree[id<<1|1]tree[id<<1]∣tree[id<<1∣1]
查询:同样道理,左儿子(如果有)异或右儿子(如果有)
代码