梦幻布丁

发布时间 2023-08-03 21:58:20作者: wscqwq

2154. 梦幻布丁

考虑先维护连续段数。

我们可以先搞几个单链表,每个单链表存储的是每种颜色处于的所有位置,由于连续段数等于相邻两数不同的个数,我们可以先算出初始的情况,然后对于每次修改,暴力的将一种颜色的所有位置修改成另外一种颜色,这种操作一定不会使得答案增加,所以我们考虑怎么样会使其减小。对于修改后,如果和左边的值相等了,答案会减少 \(1\),右边同理,这样做最坏的情况合并复杂度为 \(O(n^2)\)

考虑启发式合并,每次我们让每种颜色个数少的向个数多的合并,这样每个元素每次合并都会使得其所在集合大小至少翻倍,所以复杂度就是 \(O(n\log n)\)。而由于颜色有对应性,不能直接乱弄,所以我们考虑维护一个映射关系,如图

image-20230803212903691

我们考虑合并 \(1->2\),发现 \(|S_1|>|S_2|\),所以我们把 \(2->1\),然后将映射关系交叉交换即可,如图

image-20230803213036628

注意上图合并点还是用了一个技巧,就是直接将邻接表的 \(h_1\) 指向 \(h_2\),然后将 \(h_2\) 的末尾下一个元素指向了原来的 \(h_1\)\(h\) 表示表头),这样就不需要重新插入了。

code